Botan 2.19.5 Crypto and TLS for C&

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_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 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)

## 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_input | the share encoded in hexadecimal

Definition at line 111 of file tss.cpp.

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

References Botan::hex_decode_locked().

## ◆ RTSS_Share() [3/3]

Botan::RTSS_Share::RTSS_Share | ( | const uint8_t | data[],
|  | size_t | len
| ) |  |

Parameters

  data | the shared data
  len | the 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.

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

Referenced by share_id().

## ◆ reconstruct()

secure_vector< uint8_t > Botan::RTSS_Share::reconstruct | ( | const std::vector< RTSS_Share > & | shares | ) |
| static

Parameters

  shares | the list of shares

Definition at line 225 of file tss.cpp.

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 }
Botan::RTSS_Share::share_id
uint8_t share_id() const
Definition: tss.cpp:121
Botan::RTSS_Share::size
size_t size() const
Definition: tss.h:92
Botan::constant_time_compare
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:82
Botan::same_mem
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:217
Botan::make_uint16
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:54
hash
MechanismType hash
Definition: p11_mechanism.cpp:64

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

## ◆ share_id()

uint8_t Botan::RTSS_Share::share_id | ( |  | ) | const

Returns
  share identifier

Definition at line 121 of file tss.cpp.

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 }
Botan::RTSS_Share::initialized
bool initialized() const
Definition: tss.h:97

References initialized().

Referenced by reconstruct().

## ◆ size()

size_t Botan::RTSS_Share::size | ( |  | ) | const
| inline

Returns
  size of this share in bytes

Definition at line 92 of file tss.h.

92{ return m_contents.size(); }

Referenced by reconstruct().

## ◆ 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 std::vector< uint8_t > & | identifier,
|  | const std::string & | hash_fn,
|  | RandomNumberGenerator & | rng
| ) |  |
| static

Parameters

  M | the number of shares needed to reconstruct
  N | the number of shares generated
  secret | the secret to split
  secret_len | the length of the secret
  identifier | the share identifier
  hash_fn | the hash function to use for a checksum ("None", "SHA-1", "SHA-256")
  rng | the random number generator to use

Definition at line 150 of file tss.cpp.

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)
166 hash = HashFunction::create_or_throw(hash_fn);
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 }
Botan::HashFunction::create_or_throw
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:329
X
fe X
Definition: ge.cpp:27
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:133
Botan::get_byte
constexpr uint8_t get_byte(size_t byte_num, T input)
Definition: loadstor.h:41

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

## ◆ 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 uint8_t | identifier[16],
|  | RandomNumberGenerator & | rng
| ) |  |
| static

Parameters

  M | the number of shares needed to reconstruct
  N | the number of shares generated
  secret | the secret to split
  secret_len | the length of the secret
  identifier | the 16 byte share identifier
  rng | the 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 }
Botan::RTSS_Share::split
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

References split().

Referenced by split().

## ◆ to_string()

std::string Botan::RTSS_Share::to_string | ( |  | ) | const

Returns
  hex representation

Definition at line 132 of file tss.cpp.

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

References Botan::hex_encode().

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

- src/lib/misc/tss/tss.h
- src/lib/misc/tss/tss.cpp