Botan  2.9.0
Crypto and TLS for C++11
Public Member Functions | Static Public Member Functions | List of all members
Botan::RTSS_Share Class Referencefinal

#include <tss.h>

Public Member Functions

const secure_vector< uint8_t > & data () const
 
bool initialized () const
 
 RTSS_Share ()=default
 
 RTSS_Share (const std::string &hex_input)
 
 RTSS_Share (const uint8_t data[], size_t len)
 
uint8_t share_id () const
 
size_t size () const
 
std::string to_string () const
 

Static Public Member Functions

static secure_vector< uint8_t > reconstruct (const std::vector< RTSS_Share > &shares)
 
static std::vector< RTSS_Sharesplit (uint8_t M, uint8_t N, const uint8_t secret[], uint16_t secret_len, const uint8_t identifier[16], RandomNumberGenerator &rng)
 
static std::vector< RTSS_Sharesplit (uint8_t M, uint8_t N, const uint8_t secret[], uint16_t secret_len, const std::vector< uint8_t > &identifier, const std::string &hash_fn, RandomNumberGenerator &rng)
 

Detailed Description

A split secret, using the format from draft-mcgrew-tss-03

Definition at line 22 of file tss.h.

Constructor & Destructor Documentation

◆ RTSS_Share() [1/3]

Botan::RTSS_Share::RTSS_Share ( )
default

◆ RTSS_Share() [2/3]

Botan::RTSS_Share::RTSS_Share ( const std::string &  hex_input)
explicit
Parameters
hex_inputthe share encoded in hexadecimal

Definition at line 111 of file tss.cpp.

References Botan::hex_decode_locked().

112  {
113  m_contents = hex_decode_locked(hex_input);
114  }
secure_vector< uint8_t > hex_decode_locked(const char input[], size_t input_length, bool ignore_ws)
Definition: hex.cpp:165

◆ RTSS_Share() [3/3]

Botan::RTSS_Share::RTSS_Share ( const uint8_t  data[],
size_t  len 
)
Parameters
datathe shared data
lenthe length of data

Definition at line 116 of file tss.cpp.

117  {
118  m_contents.assign(bin, bin + len);
119  }

Member Function Documentation

◆ data()

const secure_vector<uint8_t>& Botan::RTSS_Share::data ( ) const
inline
Returns
binary representation

Definition at line 77 of file tss.h.

77 { return m_contents; }

◆ initialized()

bool Botan::RTSS_Share::initialized ( ) const
inline
Returns
if this TSS share was initialized or not

Definition at line 97 of file tss.h.

Referenced by share_id().

97 { return (m_contents.size() > 0); }

◆ reconstruct()

secure_vector< uint8_t > Botan::RTSS_Share::reconstruct ( const std::vector< RTSS_Share > &  shares)
static
Parameters
sharesthe list of shares

Definition at line 225 of file tss.cpp.

References Botan::constant_time_compare(), hash, Botan::make_uint16(), Botan::same_mem(), share_id(), and size().

226  {
227  if(shares.size() <= 1)
228  throw Decoding_Error("Insufficient shares to do TSS reconstruction");
229 
230  for(size_t i = 0; i != shares.size(); ++i)
231  {
232  if(shares[i].size() < RTSS_HEADER_SIZE + 1)
233  throw Decoding_Error("Missing or malformed RTSS header");
234 
235  if(shares[i].share_id() == 0)
236  throw Decoding_Error("Invalid (id = 0) RTSS share detected");
237 
238  if(i > 0)
239  {
240  if(shares[i].size() != shares[0].size())
241  throw Decoding_Error("Different sized RTSS shares detected");
242 
243  if(!same_mem(&shares[0].m_contents[0],
244  &shares[i].m_contents[0], RTSS_HEADER_SIZE))
245  throw Decoding_Error("Different RTSS headers detected");
246  }
247  }
248 
249  const uint8_t N = shares[0].m_contents[17];
250 
251  if(shares.size() < N)
252  throw Decoding_Error("Insufficient shares to do TSS reconstruction");
253 
254  const uint16_t share_len = make_uint16(shares[0].m_contents[18],
255  shares[0].m_contents[19]);
256 
257  const uint8_t hash_id = shares[0].m_contents[16];
258  std::unique_ptr<HashFunction> hash(get_rtss_hash_by_id(hash_id));
259  const size_t hash_len = (hash ? hash->output_length() : 0);
260 
261  if(shares[0].size() != RTSS_HEADER_SIZE + share_len)
262  {
263  /*
264  * This second (laxer) check accomodates a bug in TSS that was
265  * fixed in 2.9.0 - previous versions used the length of the
266  * *secret* here, instead of the length of the *share*, which is
267  * precisely 1 + hash_len longer.
268  */
269  if(shares[0].size() <= RTSS_HEADER_SIZE + 1 + hash_len)
270  throw Decoding_Error("Bad RTSS length field in header");
271  }
272 
273  std::vector<uint8_t> V(shares.size());
274  secure_vector<uint8_t> recovered;
275 
276  for(size_t i = RTSS_HEADER_SIZE + 1; i != shares[0].size(); ++i)
277  {
278  for(size_t j = 0; j != V.size(); ++j)
279  V[j] = shares[j].m_contents[i];
280 
281  uint8_t r = 0;
282  for(size_t k = 0; k != shares.size(); ++k)
283  {
284  // L_i function:
285  uint8_t r2 = 1;
286  for(size_t l = 0; l != shares.size(); ++l)
287  {
288  if(k == l)
289  continue;
290 
291  uint8_t share_k = shares[k].share_id();
292  uint8_t share_l = shares[l].share_id();
293 
294  if(share_k == share_l)
295  throw Decoding_Error("Duplicate shares found in RTSS recovery");
296 
297  uint8_t div = RTSS_EXP[(255 +
298  RTSS_LOG[share_l] -
299  RTSS_LOG[share_k ^ share_l]) % 255];
300 
301  r2 = gfp_mul(r2, div);
302  }
303 
304  r ^= gfp_mul(V[k], r2);
305  }
306  recovered.push_back(r);
307  }
308 
309  if(hash)
310  {
311  if(recovered.size() < hash->output_length())
312  throw Decoding_Error("RTSS recovered value too short to be valid");
313 
314  const size_t secret_len = recovered.size() - hash->output_length();
315 
316  hash->update(recovered.data(), secret_len);
317  secure_vector<uint8_t> hash_check = hash->final();
318 
319  if(!constant_time_compare(hash_check.data(),
320  &recovered[secret_len],
321  hash->output_length()))
322  {
323  throw Decoding_Error("RTSS hash check failed");
324  }
325 
326  // remove the trailing hash value
327  recovered.resize(secret_len);
328  }
329 
330  return recovered;
331  }
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:187
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:81
uint8_t share_id() const
Definition: tss.cpp:121
size_t size() const
Definition: tss.h:92
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:52
MechanismType hash

◆ share_id()

uint8_t Botan::RTSS_Share::share_id ( ) const
Returns
share identifier

Definition at line 121 of file tss.cpp.

References initialized().

Referenced by reconstruct().

122  {
123  if(!initialized())
124  throw Invalid_State("RTSS_Share::share_id not initialized");
125 
126  if(m_contents.size() < RTSS_HEADER_SIZE + 1)
127  throw Decoding_Error("RTSS_Share::share_id invalid share data");
128 
129  return m_contents[20];
130  }
bool initialized() const
Definition: tss.h:97

◆ size()

size_t Botan::RTSS_Share::size ( ) const
inline
Returns
size of this share in bytes

Definition at line 92 of file tss.h.

Referenced by reconstruct().

92 { return m_contents.size(); }

◆ split() [1/2]

std::vector< RTSS_Share > Botan::RTSS_Share::split ( uint8_t  M,
uint8_t  N,
const uint8_t  secret[],
uint16_t  secret_len,
const uint8_t  identifier[16],
RandomNumberGenerator rng 
)
static
Parameters
Mthe number of shares needed to reconstruct
Nthe number of shares generated
secretthe secret to split
secret_lenthe length of the secret
identifierthe 16 byte share identifier
rngthe random number generator to use

Definition at line 138 of file tss.cpp.

142  {
143  return RTSS_Share::split(M, N, S, S_len,
144  std::vector<uint8_t>(identifier, identifier + 16),
145  "SHA-256",
146  rng);
147  }
static std::vector< RTSS_Share > split(uint8_t M, uint8_t N, const uint8_t secret[], uint16_t secret_len, const uint8_t identifier[16], RandomNumberGenerator &rng)
Definition: tss.cpp:138

◆ split() [2/2]

std::vector< RTSS_Share > Botan::RTSS_Share::split ( uint8_t  M,
uint8_t  N,
const uint8_t  secret[],
uint16_t  secret_len,
const std::vector< uint8_t > &  identifier,
const std::string &  hash_fn,
RandomNumberGenerator rng 
)
static
Parameters
Mthe number of shares needed to reconstruct
Nthe number of shares generated
secretthe secret to split
secret_lenthe length of the secret
identifierthe share identifier
hash_fnthe hash function to use for a checksum ("None", "SHA-1", "SHA-256")
rngthe random number generator to use

Definition at line 150 of file tss.cpp.

References Botan::copy_mem(), Botan::HashFunction::create_or_throw(), Botan::get_byte(), hash, Botan::RandomNumberGenerator::randomize(), and X.

155  {
156  if(M <= 1 || N <= 1 || M > N || N >= 255)
157  throw Invalid_Argument("RTSS_Share::split: Invalid N or M");
158 
159  if(identifier.size() > 16)
160  throw Invalid_Argument("RTSS_Share::split Invalid identifier size");
161 
162  const uint8_t hash_id = rtss_hash_id(hash_fn);
163 
164  std::unique_ptr<HashFunction> hash;
165  if(hash_id > 0)
167 
168  // secret = S || H(S)
169  secure_vector<uint8_t> secret(S, S + S_len);
170  if(hash)
171  secret += hash->process(S, S_len);
172 
173  if(secret.size() >= 0xFFFE)
174  throw Encoding_Error("RTSS_Share::split secret too large for TSS format");
175 
176  // +1 byte for the share ID
177  const uint16_t share_len = static_cast<uint16_t>(secret.size() + 1);
178 
179  secure_vector<uint8_t> share_header(RTSS_HEADER_SIZE);
180  copy_mem(&share_header[0], identifier.data(), identifier.size());
181  share_header[16] = hash_id;
182  share_header[17] = M;
183  share_header[18] = get_byte(0, share_len);
184  share_header[19] = get_byte(1, share_len);
185 
186  // Create RTSS header in each share
187  std::vector<RTSS_Share> shares(N);
188 
189  for(uint8_t i = 0; i != N; ++i)
190  {
191  shares[i].m_contents.reserve(share_header.size() + share_len);
192  shares[i].m_contents = share_header;
193  }
194 
195  // Choose sequential values for X starting from 1
196  for(uint8_t i = 0; i != N; ++i)
197  shares[i].m_contents.push_back(i+1);
198 
199  for(size_t i = 0; i != secret.size(); ++i)
200  {
201  std::vector<uint8_t> coefficients(M-1);
202  rng.randomize(coefficients.data(), coefficients.size());
203 
204  for(uint8_t j = 0; j != N; ++j)
205  {
206  const uint8_t X = j + 1;
207 
208  uint8_t sum = secret[i];
209  uint8_t X_i = X;
210 
211  for(size_t k = 0; k != coefficients.size(); ++k)
212  {
213  sum ^= gfp_mul(X_i, coefficients[k]);
214  X_i = gfp_mul(X_i, X);
215  }
216 
217  shares[j].m_contents.push_back(sum);
218  }
219  }
220 
221  return shares;
222  }
fe X
Definition: ge.cpp:27
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:359
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:39
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:122
MechanismType hash

◆ to_string()

std::string Botan::RTSS_Share::to_string ( ) const
Returns
hex representation

Definition at line 132 of file tss.cpp.

References Botan::hex_encode().

133  {
134  return hex_encode(m_contents.data(), m_contents.size());
135  }
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14

The documentation for this class was generated from the following files: