Coverage Report

Created: 2023-02-13 06:21

/src/botan/src/lib/pubkey/pk_ops.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* PK Operation Types
3
* (C) 2010,2015 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/internal/pk_ops_impl.h>
9
#include <botan/internal/bit_ops.h>
10
#include <botan/rng.h>
11
12
namespace Botan {
13
14
PK_Ops::Encryption_with_EME::Encryption_with_EME(const std::string& eme) :
15
   m_eme(EME::create(eme))
16
0
   {
17
0
   }
18
19
size_t PK_Ops::Encryption_with_EME::max_input_bits() const
20
0
   {
21
0
   return 8 * m_eme->maximum_input_size(max_raw_input_bits());
22
0
   }
23
24
secure_vector<uint8_t> PK_Ops::Encryption_with_EME::encrypt(const uint8_t msg[], size_t msg_len,
25
                                                         RandomNumberGenerator& rng)
26
0
   {
27
0
   const size_t max_raw = max_raw_input_bits();
28
0
   const std::vector<uint8_t> encoded = unlock(m_eme->encode(msg, msg_len, max_raw, rng));
29
0
   return raw_encrypt(encoded.data(), encoded.size(), rng);
30
0
   }
31
32
PK_Ops::Decryption_with_EME::Decryption_with_EME(const std::string& eme) :
33
   m_eme(EME::create(eme))
34
0
   {
35
0
   }
36
37
secure_vector<uint8_t>
38
PK_Ops::Decryption_with_EME::decrypt(uint8_t& valid_mask,
39
                                     const uint8_t ciphertext[],
40
                                     size_t ciphertext_len)
41
0
   {
42
0
   const secure_vector<uint8_t> raw = raw_decrypt(ciphertext, ciphertext_len);
43
0
   return m_eme->unpad(valid_mask, raw.data(), raw.size());
44
0
   }
45
46
PK_Ops::Key_Agreement_with_KDF::Key_Agreement_with_KDF(const std::string& kdf)
47
13.8k
   {
48
13.8k
   if(kdf != "Raw")
49
0
      m_kdf = KDF::create_or_throw(kdf);
50
13.8k
   }
51
52
secure_vector<uint8_t> PK_Ops::Key_Agreement_with_KDF::agree(size_t key_len,
53
                                                          const uint8_t w[], size_t w_len,
54
                                                          const uint8_t salt[], size_t salt_len)
55
13.8k
   {
56
13.8k
   secure_vector<uint8_t> z = raw_agree(w, w_len);
57
13.8k
   if(m_kdf)
58
0
      return m_kdf->derive_key(key_len, z, salt, salt_len);
59
13.8k
   return z;
60
13.8k
   }
61
62
PK_Ops::Signature_with_EMSA::Signature_with_EMSA(const std::string& emsa, bool with_message_recovery) :
63
   Signature(),
64
   m_emsa(EMSA::create_or_throw(emsa)),
65
   m_hash(hash_for_emsa(emsa)),
66
   m_prefix_used(false)
67
0
   {
68
0
   if(!with_message_recovery && m_emsa->requires_message_recovery())
69
0
      {
70
0
      throw Invalid_Argument("Signature padding method " + emsa +
71
0
                             " requires message recovery, which is not supported by this scheme");
72
0
      }
73
0
   }
74
75
void PK_Ops::Signature_with_EMSA::update(const uint8_t msg[], size_t msg_len)
76
0
   {
77
0
   if(has_prefix() && !m_prefix_used)
78
0
      {
79
0
      m_prefix_used = true;
80
0
      secure_vector<uint8_t> prefix = message_prefix();
81
0
      m_emsa->update(prefix.data(), prefix.size());
82
0
      }
83
0
   m_emsa->update(msg, msg_len);
84
0
   }
85
86
secure_vector<uint8_t> PK_Ops::Signature_with_EMSA::sign(RandomNumberGenerator& rng)
87
0
   {
88
0
   m_prefix_used = false;
89
0
   const secure_vector<uint8_t> msg = m_emsa->raw_data();
90
0
   const auto padded = m_emsa->encoding_of(msg, this->max_input_bits(), rng);
91
0
   return raw_sign(padded.data(), padded.size(), rng);
92
0
   }
93
94
PK_Ops::Verification_with_EMSA::Verification_with_EMSA(const std::string& emsa, bool with_message_recovery) :
95
   Verification(),
96
   m_emsa(EMSA::create_or_throw(emsa)),
97
   m_hash(hash_for_emsa(emsa)),
98
   m_prefix_used(false)
99
8.76k
   {
100
8.76k
   if(!with_message_recovery && m_emsa->requires_message_recovery())
101
0
      {
102
0
      throw Invalid_Argument("Signature padding method " + emsa +
103
0
                             " requires message recovery, which is not supported by this scheme");
104
0
      }
105
8.76k
   }
106
107
void PK_Ops::Verification_with_EMSA::update(const uint8_t msg[], size_t msg_len)
108
8.76k
   {
109
8.76k
   if(has_prefix() && !m_prefix_used)
110
0
      {
111
0
      m_prefix_used = true;
112
0
      secure_vector<uint8_t> prefix = message_prefix();
113
0
      m_emsa->update(prefix.data(), prefix.size());
114
0
      }
115
8.76k
   m_emsa->update(msg, msg_len);
116
8.76k
   }
117
118
bool PK_Ops::Verification_with_EMSA::is_valid_signature(const uint8_t sig[], size_t sig_len)
119
8.47k
   {
120
8.47k
   m_prefix_used = false;
121
8.47k
   const secure_vector<uint8_t> msg = m_emsa->raw_data();
122
123
8.47k
   if(with_recovery())
124
7.98k
      {
125
7.98k
      secure_vector<uint8_t> output_of_key = verify_mr(sig, sig_len);
126
7.98k
      return m_emsa->verify(output_of_key, msg, max_input_bits());
127
7.98k
      }
128
488
   else
129
488
      {
130
488
      Null_RNG rng;
131
488
      secure_vector<uint8_t> encoded = m_emsa->encoding_of(msg, max_input_bits(), rng);
132
488
      return verify(encoded.data(), encoded.size(), sig, sig_len);
133
488
      }
134
8.47k
   }
135
136
void PK_Ops::KEM_Encryption_with_KDF::kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
137
                                                  secure_vector<uint8_t>& out_shared_key,
138
                                                  size_t desired_shared_key_len,
139
                                                  RandomNumberGenerator& rng,
140
                                                  const uint8_t salt[],
141
                                                  size_t salt_len)
142
0
   {
143
0
   secure_vector<uint8_t> raw_shared;
144
0
   this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng);
145
146
0
   out_shared_key = (m_kdf)
147
0
      ? m_kdf->derive_key(desired_shared_key_len,
148
0
                          raw_shared.data(), raw_shared.size(),
149
0
                          salt, salt_len)
150
0
      : raw_shared;
151
0
   }
152
153
PK_Ops::KEM_Encryption_with_KDF::KEM_Encryption_with_KDF(const std::string& kdf)
154
0
   {
155
0
   if(kdf != "Raw")
156
0
      m_kdf = KDF::create_or_throw(kdf);
157
0
   }
158
159
secure_vector<uint8_t>
160
PK_Ops::KEM_Decryption_with_KDF::kem_decrypt(const uint8_t encap_key[],
161
                                             size_t len,
162
                                             size_t desired_shared_key_len,
163
                                             const uint8_t salt[],
164
                                             size_t salt_len)
165
0
   {
166
0
   secure_vector<uint8_t> raw_shared = this->raw_kem_decrypt(encap_key, len);
167
168
0
   if(m_kdf)
169
0
      return m_kdf->derive_key(desired_shared_key_len,
170
0
                               raw_shared.data(), raw_shared.size(),
171
0
                               salt, salt_len);
172
0
   return raw_shared;
173
0
   }
174
175
PK_Ops::KEM_Decryption_with_KDF::KEM_Decryption_with_KDF(const std::string& kdf)
176
0
   {
177
0
   if(kdf != "Raw")
178
0
      m_kdf = KDF::create_or_throw(kdf);
179
0
   }
180
181
}