Coverage Report

Created: 2022-01-14 08:07

/src/botan/src/lib/pubkey/dh/dh.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Diffie-Hellman
3
* (C) 1999-2007,2016,2019 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/dh.h>
9
#include <botan/internal/pk_ops_impl.h>
10
#include <botan/internal/monty_exp.h>
11
#include <botan/internal/blinding.h>
12
13
namespace Botan {
14
15
/*
16
* DH_PublicKey Constructor
17
*/
18
DH_PublicKey::DH_PublicKey(const DL_Group& grp, const BigInt& y1)
19
0
   {
20
0
   m_group = grp;
21
0
   m_y = y1;
22
0
   }
Unexecuted instantiation: Botan::DH_PublicKey::DH_PublicKey(Botan::DL_Group const&, Botan::BigInt const&)
Unexecuted instantiation: Botan::DH_PublicKey::DH_PublicKey(Botan::DL_Group const&, Botan::BigInt const&)
23
24
/*
25
* Return the public value for key agreement
26
*/
27
std::vector<uint8_t> DH_PublicKey::public_value() const
28
0
   {
29
0
   return unlock(BigInt::encode_1363(m_y, group_p().bytes()));
30
0
   }
31
32
/*
33
* Create a DH private key
34
*/
35
DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng,
36
                             const DL_Group& grp,
37
                             const BigInt& x_arg)
38
0
   {
39
0
   m_group = grp;
40
41
0
   if(x_arg == 0)
42
0
      {
43
0
      const size_t exp_bits = grp.exponent_bits();
44
0
      m_x.randomize(rng, exp_bits);
45
0
      m_y = m_group.power_g_p(m_x, exp_bits);
46
0
      }
47
0
   else
48
0
      {
49
0
      m_x = x_arg;
50
51
0
      if(m_y == 0)
52
0
         m_y = m_group.power_g_p(m_x, grp.p_bits());
53
0
      }
54
0
   }
Unexecuted instantiation: Botan::DH_PrivateKey::DH_PrivateKey(Botan::RandomNumberGenerator&, Botan::DL_Group const&, Botan::BigInt const&)
Unexecuted instantiation: Botan::DH_PrivateKey::DH_PrivateKey(Botan::RandomNumberGenerator&, Botan::DL_Group const&, Botan::BigInt const&)
55
56
/*
57
* Load a DH private key
58
*/
59
DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id,
60
                             const secure_vector<uint8_t>& key_bits) :
61
   DL_Scheme_PrivateKey(alg_id, key_bits, DL_Group_Format::ANSI_X9_42)
62
59
   {
63
59
   if(m_y.is_zero())
64
27
      {
65
27
      m_y = m_group.power_g_p(m_x, m_group.p_bits());
66
27
      }
67
59
   }
Unexecuted instantiation: Botan::DH_PrivateKey::DH_PrivateKey(Botan::AlgorithmIdentifier const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Botan::DH_PrivateKey::DH_PrivateKey(Botan::AlgorithmIdentifier const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Line
Count
Source
62
59
   {
63
59
   if(m_y.is_zero())
64
27
      {
65
27
      m_y = m_group.power_g_p(m_x, m_group.p_bits());
66
27
      }
67
59
   }
68
69
std::unique_ptr<Public_Key> DH_PrivateKey::public_key() const
70
0
   {
71
0
   return std::make_unique<DH_PublicKey>(get_group(), get_y());
72
0
   }
73
74
/*
75
* Return the public value for key agreement
76
*/
77
std::vector<uint8_t> DH_PrivateKey::public_value() const
78
0
   {
79
0
   return DH_PublicKey::public_value();
80
0
   }
81
82
namespace {
83
84
/**
85
* DH operation
86
*/
87
class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
88
   {
89
   public:
90
91
      DH_KA_Operation(const DH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) :
92
         PK_Ops::Key_Agreement_with_KDF(kdf),
93
         m_p(key.group_p()),
94
         m_x(key.get_x()),
95
         m_x_bits(m_x.bits()),
96
         m_monty_p(key.get_group().monty_params_p()),
97
         m_blinder(m_p,
98
                   rng,
99
0
                   [](const BigInt& k) { return k; },
100
0
                   [this](const BigInt& k) { return powermod_x_p(inverse_mod(k, m_p)); })
101
0
         {}
102
103
0
      size_t agreed_value_size() const override { return m_p.bytes(); }
104
105
      secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override;
106
   private:
107
      BigInt powermod_x_p(const BigInt& v) const
108
0
         {
109
0
         const size_t powm_window = 4;
110
0
         auto powm_v_p = monty_precompute(m_monty_p, v, powm_window);
111
0
         return monty_execute(*powm_v_p, m_x, m_x_bits);
112
0
         }
113
114
      const BigInt& m_p;
115
      const BigInt& m_x;
116
      const size_t m_x_bits;
117
      std::shared_ptr<const Montgomery_Params> m_monty_p;
118
      Blinder m_blinder;
119
   };
120
121
secure_vector<uint8_t> DH_KA_Operation::raw_agree(const uint8_t w[], size_t w_len)
122
0
   {
123
0
   BigInt v = BigInt::decode(w, w_len);
124
125
0
   if(v <= 1 || v >= m_p - 1)
126
0
      throw Invalid_Argument("DH agreement - invalid key provided");
127
128
0
   v = m_blinder.blind(v);
129
0
   v = powermod_x_p(v);
130
0
   v = m_blinder.unblind(v);
131
132
0
   return BigInt::encode_1363(v, m_p.bytes());
133
0
   }
134
135
}
136
137
std::unique_ptr<PK_Ops::Key_Agreement>
138
DH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng,
139
                                       const std::string& params,
140
                                       const std::string& provider) const
141
0
   {
142
0
   if(provider == "base" || provider.empty())
143
0
      return std::make_unique<DH_KA_Operation>(*this, params, rng);
144
0
   throw Provider_Not_Found(algo_name(), provider);
145
0
   }
146
147
}