Botan 3.6.1
Crypto and TLS for C&
x25519.cpp
Go to the documentation of this file.
1/*
2* X25519
3* (C) 2014,2024 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/x25519.h>
9
10#include <botan/ber_dec.h>
11#include <botan/der_enc.h>
12#include <botan/rng.h>
13#include <botan/internal/ct_utils.h>
14#include <botan/internal/fmt.h>
15#include <botan/internal/pk_ops_impl.h>
16
17namespace Botan {
18
19void curve25519_basepoint(uint8_t mypublic[32], const uint8_t secret[32]) {
20 const uint8_t basepoint[32] = {9};
21 curve25519_donna(mypublic, secret, basepoint);
22}
23
24namespace {
25
26void size_check(size_t size, const char* thing) {
27 if(size != 32) {
28 throw Decoding_Error(fmt("Invalid size {} for X25519 {}", size, thing));
29 }
30}
31
32secure_vector<uint8_t> curve25519(const secure_vector<uint8_t>& secret, const uint8_t pubval[32]) {
34 curve25519_donna(out.data(), secret.data(), pubval);
35 return out;
36}
37
38} // namespace
39
43
44bool X25519_PublicKey::check_key(RandomNumberGenerator& /*rng*/, bool /*strong*/) const {
45 return true; // no tests possible?
46}
47
48X25519_PublicKey::X25519_PublicKey(const AlgorithmIdentifier& /*unused*/, std::span<const uint8_t> key_bits) :
49 X25519_PublicKey(key_bits) {}
50
51X25519_PublicKey::X25519_PublicKey(std::span<const uint8_t> pub) {
52 m_public.assign(pub.begin(), pub.end());
53
54 size_check(m_public.size(), "public key");
55}
56
57std::vector<uint8_t> X25519_PublicKey::raw_public_key_bits() const {
58 return m_public;
59}
60
61std::vector<uint8_t> X25519_PublicKey::public_key_bits() const {
62 return raw_public_key_bits();
63}
64
65std::unique_ptr<Private_Key> X25519_PublicKey::generate_another(RandomNumberGenerator& rng) const {
66 return std::make_unique<X25519_PrivateKey>(rng);
67}
68
70 if(secret_key.size() != 32) {
71 throw Decoding_Error("Invalid size for X25519 private key");
72 }
73
74 m_public.resize(32);
75 m_private = secret_key;
76 curve25519_basepoint(m_public.data(), m_private.data());
77}
78
80 m_private = rng.random_vec(32);
81 m_public.resize(32);
82 curve25519_basepoint(m_public.data(), m_private.data());
83}
84
85X25519_PrivateKey::X25519_PrivateKey(const AlgorithmIdentifier& /*unused*/, std::span<const uint8_t> key_bits) {
87
88 size_check(m_private.size(), "private key");
89 m_public.resize(32);
90 curve25519_basepoint(m_public.data(), m_private.data());
91}
92
93std::unique_ptr<Public_Key> X25519_PrivateKey::public_key() const {
94 return std::make_unique<X25519_PublicKey>(public_value());
95}
96
100
101bool X25519_PrivateKey::check_key(RandomNumberGenerator& /*rng*/, bool /*strong*/) const {
102 std::vector<uint8_t> public_point(32);
103 curve25519_basepoint(public_point.data(), m_private.data());
104 return public_point == m_public;
105}
106
107secure_vector<uint8_t> X25519_PrivateKey::agree(const uint8_t w[], size_t w_len) const {
108 size_check(w_len, "public value");
109 return curve25519(m_private, w);
110}
111
112namespace {
113
114/**
115* X25519 operation
116*/
117class X25519_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF {
118 public:
119 X25519_KA_Operation(const X25519_PrivateKey& key, std::string_view kdf) :
120 PK_Ops::Key_Agreement_with_KDF(kdf), m_key(key) {}
121
122 size_t agreed_value_size() const override { return 32; }
123
124 secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override {
125 auto shared_key = m_key.agree(w, w_len);
126
127 // RFC 7748 Section 6.1
128 // Both [parties] MAY check, without leaking extra information about
129 // the value of K, whether K is the all-zero value and abort if so.
130 //
131 // TODO: once the generic Key Agreement operation creation is equipped
132 // with a more flexible parameterization, this check could be
133 // made optional.
134 // For instance: `sk->agree().with_optional_sanity_checks(true)`.
135 // See also: https://github.com/randombit/botan/pull/4318
136 if(CT::all_zeros(shared_key.data(), shared_key.size()).as_bool()) {
137 throw Invalid_Argument("X25519 public point appears to be of low order");
138 }
139
140 return shared_key;
141 }
142
143 private:
144 const X25519_PrivateKey& m_key;
145};
146
147} // namespace
148
149std::unique_ptr<PK_Ops::Key_Agreement> X25519_PrivateKey::create_key_agreement_op(RandomNumberGenerator& /*rng*/,
150 std::string_view params,
151 std::string_view provider) const {
152 if(provider == "base" || provider.empty()) {
153 return std::make_unique<X25519_KA_Operation>(*this, params);
154 }
155 throw Provider_Not_Found(algo_name(), provider);
156}
157
158} // namespace Botan
virtual OID object_identifier() const
Definition pk_keys.cpp:22
BER_Decoder & decode(bool &out)
Definition ber_dec.h:186
BER_Decoder & discard_remaining()
Definition ber_dec.cpp:228
secure_vector< uint8_t > get_contents()
Definition der_enc.cpp:132
DER_Encoder & encode(bool b)
Definition der_enc.cpp:250
void random_vec(std::span< uint8_t > v)
Definition rng.h:180
secure_vector< uint8_t > private_key_bits() const override
Definition x25519.cpp:97
secure_vector< uint8_t > agree(const uint8_t w[], size_t w_len) const
Definition x25519.cpp:107
std::unique_ptr< Public_Key > public_key() const override
Definition x25519.cpp:93
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition x25519.cpp:101
std::vector< uint8_t > public_value() const override
Definition x25519.h:80
std::unique_ptr< PK_Ops::Key_Agreement > create_key_agreement_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
Definition x25519.cpp:149
X25519_PrivateKey(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
Definition x25519.cpp:85
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition x25519.cpp:44
std::string algo_name() const override
Definition x25519.h:16
std::vector< uint8_t > raw_public_key_bits() const override
Definition x25519.cpp:57
AlgorithmIdentifier algorithm_identifier() const override
Definition x25519.cpp:40
std::vector< uint8_t > m_public
Definition x25519.h:51
std::vector< uint8_t > public_key_bits() const override
Definition x25519.cpp:61
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const final
Definition x25519.cpp:65
int(* final)(unsigned char *, CTX *)
constexpr CT::Mask< T > all_zeros(const T elem[], size_t len)
Definition ct_utils.h:746
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
void curve25519_donna(uint8_t mypublic[32], const uint8_t secret[32], const uint8_t basepoint[32])
Definition donna.cpp:454
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
void curve25519_basepoint(uint8_t mypublic[32], const uint8_t secret[32])
Definition x25519.cpp:19