aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/ffi/ffi.h2
-rw-r--r--src/lib/ffi/ffi_pk_op.cpp7
-rw-r--r--src/lib/prov/pkcs11/p11_ecdh.cpp1
-rw-r--r--src/lib/pubkey/curve25519/curve25519.cpp2
-rw-r--r--src/lib/pubkey/dh/dh.cpp2
-rw-r--r--src/lib/pubkey/ecdh/ecdh.cpp2
-rw-r--r--src/lib/pubkey/ecies/ecies.cpp2
-rw-r--r--src/lib/pubkey/pk_ops.h6
-rw-r--r--src/lib/pubkey/pubkey.cpp5
-rw-r--r--src/lib/pubkey/pubkey.h17
-rw-r--r--src/tests/test_pubkey.cpp9
11 files changed, 47 insertions, 8 deletions
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index fe847e94a..96cdf1de4 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -1203,6 +1203,8 @@ BOTAN_PUBLIC_API(2,0) int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op)
BOTAN_PUBLIC_API(2,0) int botan_pk_op_key_agreement_export_public(botan_privkey_t key,
uint8_t out[], size_t* out_len);
+BOTAN_PUBLIC_API(2,8) int botan_pk_op_key_agreement_size(botan_pk_op_ka_t op, size_t* out_len);
+
BOTAN_PUBLIC_API(2,0)
int botan_pk_op_key_agreement(botan_pk_op_ka_t op,
uint8_t out[], size_t* out_len,
diff --git a/src/lib/ffi/ffi_pk_op.cpp b/src/lib/ffi/ffi_pk_op.cpp
index 5f2437a10..4e548fff8 100644
--- a/src/lib/ffi/ffi_pk_op.cpp
+++ b/src/lib/ffi/ffi_pk_op.cpp
@@ -221,6 +221,13 @@ int botan_pk_op_key_agreement_export_public(botan_privkey_t key,
});
}
+int botan_pk_op_key_agreement_size(botan_pk_op_ka_t op, size_t* out_len)
+ {
+ return BOTAN_FFI_DO(Botan::PK_Key_Agreement, op, o, {
+ *out_len = o.agreed_value_size();
+ });
+ }
+
int botan_pk_op_key_agreement(botan_pk_op_ka_t op,
uint8_t out[], size_t* out_len,
const uint8_t other_key[], size_t other_key_len,
diff --git a/src/lib/prov/pkcs11/p11_ecdh.cpp b/src/lib/prov/pkcs11/p11_ecdh.cpp
index d7b0fae5c..0cd671bcb 100644
--- a/src/lib/prov/pkcs11/p11_ecdh.cpp
+++ b/src/lib/prov/pkcs11/p11_ecdh.cpp
@@ -45,6 +45,7 @@ class PKCS11_ECDH_KA_Operation final : public PK_Ops::Key_Agreement
: PK_Ops::Key_Agreement(), m_key(key), m_mechanism(MechanismWrapper::create_ecdh_mechanism(params))
{}
+ size_t agreed_value_size() const override { return m_key.domain().get_p_bytes(); }
/// The encoding in V2.20 was not specified and resulted in different implementations choosing different encodings.
/// Applications relying only on a V2.20 encoding (e.g. the DER variant) other than the one specified now (raw) may not work with all V2.30 compliant tokens.
diff --git a/src/lib/pubkey/curve25519/curve25519.cpp b/src/lib/pubkey/curve25519/curve25519.cpp
index c43f526a8..68b4f5a4f 100644
--- a/src/lib/pubkey/curve25519/curve25519.cpp
+++ b/src/lib/pubkey/curve25519/curve25519.cpp
@@ -118,6 +118,8 @@ class Curve25519_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
PK_Ops::Key_Agreement_with_KDF(kdf),
m_key(key) {}
+ size_t agreed_value_size() const { return 32; }
+
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
{
return m_key.agree(w, w_len);
diff --git a/src/lib/pubkey/dh/dh.cpp b/src/lib/pubkey/dh/dh.cpp
index ae6e9c589..75b0db2f6 100644
--- a/src/lib/pubkey/dh/dh.cpp
+++ b/src/lib/pubkey/dh/dh.cpp
@@ -93,6 +93,8 @@ class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
[this](const BigInt& k) { return m_powermod_x_p(inverse_mod(k, m_p)); })
{}
+ size_t agreed_value_size() const override { return m_p.bytes(); }
+
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override;
private:
const BigInt& m_p;
diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp
index 59f245a00..e7e49a74f 100644
--- a/src/lib/pubkey/ecdh/ecdh.cpp
+++ b/src/lib/pubkey/ecdh/ecdh.cpp
@@ -34,6 +34,8 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
m_l_times_priv = m_group.inverse_mod_order(m_group.get_cofactor()) * key.private_value();
}
+ size_t agreed_value_size() const override { return m_group.get_p_bytes(); }
+
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
{
PointGFp input_point = m_group.get_cofactor() * m_group.OS2ECP(w, w_len);
diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp
index 8f5c445ed..ebfd9121e 100644
--- a/src/lib/pubkey/ecies/ecies.cpp
+++ b/src/lib/pubkey/ecies/ecies.cpp
@@ -64,6 +64,8 @@ class ECIES_ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
{
}
+ size_t agreed_value_size() const { return m_key.domain().get_p_bytes(); }
+
secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
{
const EC_Group& group = m_key.domain();
diff --git a/src/lib/pubkey/pk_ops.h b/src/lib/pubkey/pk_ops.h
index 3f794f00d..63ef9fa9b 100644
--- a/src/lib/pubkey/pk_ops.h
+++ b/src/lib/pubkey/pk_ops.h
@@ -118,8 +118,10 @@ class BOTAN_PUBLIC_API(2,0) Key_Agreement
{
public:
virtual secure_vector<uint8_t> agree(size_t key_len,
- const uint8_t other_key[], size_t other_key_len,
- const uint8_t salt[], size_t salt_len) = 0;
+ const uint8_t other_key[], size_t other_key_len,
+ const uint8_t salt[], size_t salt_len) = 0;
+
+ virtual size_t agreed_value_size() const = 0;
virtual ~Key_Agreement() = default;
};
diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp
index fef81a620..bb0170548 100644
--- a/src/lib/pubkey/pubkey.cpp
+++ b/src/lib/pubkey/pubkey.cpp
@@ -210,6 +210,11 @@ PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&& other) :
m_op(std::move(other.m_op))
{}
+size_t PK_Key_Agreement::agreed_value_size() const
+ {
+ return m_op->agreed_value_size();
+ }
+
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
const uint8_t in[], size_t in_len,
const uint8_t salt[],
diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h
index a1404135d..43e1f987a 100644
--- a/src/lib/pubkey/pubkey.h
+++ b/src/lib/pubkey/pubkey.h
@@ -412,7 +412,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Verifier final
};
/**
-* Key used for key agreement
+* Object used for key agreement
*/
class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final
{
@@ -454,7 +454,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final
PK_Key_Agreement& operator=(const PK_Key_Agreement&) = delete;
PK_Key_Agreement(const PK_Key_Agreement&) = delete;
- /*
+ /**
* Perform Key Agreement Operation
* @param key_len the desired key output size
* @param in the other parties key
@@ -468,7 +468,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final
const uint8_t params[],
size_t params_len) const;
- /*
+ /**
* Perform Key Agreement Operation
* @param key_len the desired key output size
* @param in the other parties key
@@ -485,7 +485,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final
params, params_len);
}
- /*
+ /**
* Perform Key Agreement Operation
* @param key_len the desired key output size
* @param in the other parties key
@@ -501,7 +501,7 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final
params.length());
}
- /*
+ /**
* Perform Key Agreement Operation
* @param key_len the desired key output size
* @param in the other parties key
@@ -516,6 +516,13 @@ class BOTAN_PUBLIC_API(2,0) PK_Key_Agreement final
params.length());
}
+ /**
+ * Return the underlying size of the value that is agreed.
+ * If derive_key is called with a length of 0 with a "Raw"
+ * KDF, it will return a value of this size.
+ */
+ size_t agreed_value_size() const;
+
private:
std::unique_ptr<PK_Ops::Key_Agreement> m_op;
};
diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp
index bc2d19bb7..765e7e396 100644
--- a/src/tests/test_pubkey.cpp
+++ b/src/tests/test_pubkey.cpp
@@ -509,7 +509,14 @@ Test::Result PK_Key_Agreement_Test::run_one_test(const std::string& header, cons
try
{
kas.reset(new Botan::PK_Key_Agreement(*privkey, Test::rng(), kdf, provider));
- result.test_eq(provider, "agreement", kas->derive_key(key_len, pubkey).bits_of(), shared);
+
+ auto derived_key = kas->derive_key(key_len, pubkey).bits_of();
+ result.test_eq(provider, "agreement", derived_key, shared);
+
+ if(key_len == 0 && kdf == "Raw")
+ {
+ result.test_eq("Expected size", derived_key.size(), kas->agreed_value_size());
+ }
}
catch(Botan::Lookup_Error&)
{