Coverage Report

Created: 2020-03-26 13:53

/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/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
82
   {
20
82
   m_group = grp;
21
82
   m_y = y1;
22
82
   }
Unexecuted instantiation: Botan::DH_PublicKey::DH_PublicKey(Botan::DL_Group const&, Botan::BigInt const&)
Botan::DH_PublicKey::DH_PublicKey(Botan::DL_Group const&, Botan::BigInt const&)
Line
Count
Source
19
82
   {
20
82
   m_group = grp;
21
82
   m_y = y1;
22
82
   }
23
24
/*
25
* Return the public value for key agreement
26
*/
27
std::vector<uint8_t> DH_PublicKey::public_value() const
28
5.93k
   {
29
5.93k
   return unlock(BigInt::encode_1363(m_y, group_p().bytes()));
30
5.93k
   }
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
5.93k
   {
39
5.93k
   m_group = grp;
40
5.93k
41
5.93k
   if(x_arg == 0)
42
5.93k
      {
43
5.93k
      const size_t exp_bits = grp.exponent_bits();
44
5.93k
      m_x.randomize(rng, exp_bits);
45
5.93k
      m_y = m_group.power_g_p(m_x, exp_bits);
46
5.93k
      }
47
0
   else
48
0
      {
49
0
      m_x = x_arg;
50
0
51
0
      if(m_y == 0)
52
0
         m_y = m_group.power_g_p(m_x, grp.p_bits());
53
0
      }
54
5.93k
   }
Unexecuted instantiation: Botan::DH_PrivateKey::DH_PrivateKey(Botan::RandomNumberGenerator&, Botan::DL_Group const&, Botan::BigInt const&)
Botan::DH_PrivateKey::DH_PrivateKey(Botan::RandomNumberGenerator&, Botan::DL_Group const&, Botan::BigInt const&)
Line
Count
Source
38
5.93k
   {
39
5.93k
   m_group = grp;
40
5.93k
41
5.93k
   if(x_arg == 0)
42
5.93k
      {
43
5.93k
      const size_t exp_bits = grp.exponent_bits();
44
5.93k
      m_x.randomize(rng, exp_bits);
45
5.93k
      m_y = m_group.power_g_p(m_x, exp_bits);
46
5.93k
      }
47
0
   else
48
0
      {
49
0
      m_x = x_arg;
50
0
51
0
      if(m_y == 0)
52
0
         m_y = m_group.power_g_p(m_x, grp.p_bits());
53
0
      }
54
5.93k
   }
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::ANSI_X9_42)
62
44
   {
63
44
   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
44
   }
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
44
   {
63
44
   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
44
   }
68
69
/*
70
* Return the public value for key agreement
71
*/
72
std::vector<uint8_t> DH_PrivateKey::public_value() const
73
5.93k
   {
74
5.93k
   return DH_PublicKey::public_value();
75
5.93k
   }
76
77
namespace {
78
79
/**
80
* DH operation
81
*/
82
class DH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
83
   {
84
   public:
85
86
      DH_KA_Operation(const DH_PrivateKey& key, const std::string& kdf, RandomNumberGenerator& rng) :
87
         PK_Ops::Key_Agreement_with_KDF(kdf),
88
         m_p(key.group_p()),
89
         m_x(key.get_x()),
90
         m_x_bits(m_x.bits()),
91
         m_monty_p(key.get_group().monty_params_p()),
92
         m_blinder(m_p,
93
                   rng,
94
2.58k
                   [](const BigInt& k) { return k; },
95
2.58k
                   [this](const BigInt& k) { return powermod_x_p(inverse_mod(k, m_p)); })
96
2.58k
         {}
97
98
0
      size_t agreed_value_size() const override { return m_p.bytes(); }
99
100
      secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override;
101
   private:
102
      BigInt powermod_x_p(const BigInt& v) const
103
5.13k
         {
104
5.13k
         const size_t powm_window = 4;
105
5.13k
         auto powm_v_p = monty_precompute(m_monty_p, v, powm_window);
106
5.13k
         return monty_execute(*powm_v_p, m_x, m_x_bits);
107
5.13k
         }
108
109
      const BigInt& m_p;
110
      const BigInt& m_x;
111
      const size_t m_x_bits;
112
      std::shared_ptr<const Montgomery_Params> m_monty_p;
113
      Blinder m_blinder;
114
   };
115
116
secure_vector<uint8_t> DH_KA_Operation::raw_agree(const uint8_t w[], size_t w_len)
117
2.58k
   {
118
2.58k
   BigInt v = BigInt::decode(w, w_len);
119
2.58k
120
2.58k
   if(v <= 1 || v >= m_p - 1)
121
30
      throw Invalid_Argument("DH agreement - invalid key provided");
122
2.55k
123
2.55k
   v = m_blinder.blind(v);
124
2.55k
   v = powermod_x_p(v);
125
2.55k
   v = m_blinder.unblind(v);
126
2.55k
127
2.55k
   return BigInt::encode_1363(v, m_p.bytes());
128
2.55k
   }
129
130
}
131
132
std::unique_ptr<PK_Ops::Key_Agreement>
133
DH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng,
134
                                       const std::string& params,
135
                                       const std::string& provider) const
136
2.58k
   {
137
2.58k
   if(provider == "base" || provider.empty())
138
2.58k
      return std::unique_ptr<PK_Ops::Key_Agreement>(new DH_KA_Operation(*this, params, rng));
139
0
   throw Provider_Not_Found(algo_name(), provider);
140
0
   }
141
142
}