Botan 1.10.17
x931_rng.cpp
Go to the documentation of this file.
1/*
2* ANSI X9.31 RNG
3* (C) 1999-2009 Jack Lloyd
4*
5* Distributed under the terms of the Botan license
6*/
7
8#include <botan/x931_rng.h>
9#include <botan/internal/xor_buf.h>
10#include <algorithm>
11
12namespace Botan {
13
14/*
15* Generate a buffer of random bytes
16*/
17void ANSI_X931_RNG::randomize(byte out[], size_t length)
18 {
19 if(!is_seeded())
20 throw PRNG_Unseeded(name());
21
22 while(length)
23 {
24 if(position == R.size())
25 update_buffer();
26
27 const size_t copied = std::min<size_t>(length, R.size() - position);
28
29 copy_mem(out, &R[position], copied);
30 out += copied;
31 length -= copied;
32 position += copied;
33 }
34 }
35
36/*
37* Refill the internal state
38*/
39void ANSI_X931_RNG::update_buffer()
40 {
41 const size_t BLOCK_SIZE = cipher->block_size();
42
43 SecureVector<byte> DT = prng->random_vec(BLOCK_SIZE);
44 cipher->encrypt(DT);
45
46 xor_buf(&R[0], &V[0], &DT[0], BLOCK_SIZE);
47 cipher->encrypt(R);
48
49 xor_buf(&V[0], &R[0], &DT[0], BLOCK_SIZE);
50 cipher->encrypt(V);
51
52 position = 0;
53 }
54
55/*
56* Reset V and the cipher key with new values
57*/
58void ANSI_X931_RNG::rekey()
59 {
60 const size_t BLOCK_SIZE = cipher->block_size();
61
62 if(prng->is_seeded())
63 {
64 cipher->set_key(prng->random_vec(cipher->maximum_keylength()));
65
66 if(V.size() != BLOCK_SIZE)
67 V.resize(BLOCK_SIZE);
68 prng->randomize(&V[0], V.size());
69
70 update_buffer();
71 }
72 }
73
74/*
75* Reseed the internal state
76*/
77void ANSI_X931_RNG::reseed(size_t poll_bits)
78 {
79 prng->reseed(poll_bits);
80 rekey();
81 }
82
83/*
84* Add a entropy source to the underlying PRNG
85*/
87 {
88 prng->add_entropy_source(src);
89 }
90
91/*
92* Add some entropy to the underlying PRNG
93*/
94void ANSI_X931_RNG::add_entropy(const byte input[], size_t length)
95 {
96 prng->add_entropy(input, length);
97 rekey();
98 }
99
100/*
101* Check if the the PRNG is seeded
102*/
104 {
105 return (V.size() > 0);
106 }
107
108/*
109* Clear memory of sensitive data
110*/
112 {
113 cipher->clear();
114 prng->clear();
115 zeroise(R);
116 V.clear();
117
118 position = 0;
119 }
120
121/*
122* Return the name of this type
123*/
124std::string ANSI_X931_RNG::name() const
125 {
126 return "X9.31(" + cipher->name() + ")";
127 }
128
129/*
130* ANSI X931 RNG Constructor
131*/
133 RandomNumberGenerator* prng_in)
134 {
135 if(!prng_in || !cipher_in)
136 throw Invalid_Argument("ANSI_X931_RNG constructor: NULL arguments");
137
138 cipher = cipher_in;
139 prng = prng_in;
140
141 R.resize(cipher->block_size());
142 position = 0;
143 }
144
145/*
146* ANSI X931 RNG Destructor
147*/
149 {
150 delete cipher;
151 delete prng;
152 }
153
154}
bool is_seeded() const
Definition x931_rng.cpp:103
void reseed(size_t poll_bits)
Definition x931_rng.cpp:77
ANSI_X931_RNG(BlockCipher *cipher, RandomNumberGenerator *rng)
Definition x931_rng.cpp:132
void add_entropy(const byte[], size_t)
Definition x931_rng.cpp:94
void randomize(byte[], size_t)
Definition x931_rng.cpp:17
void add_entropy_source(EntropySource *)
Definition x931_rng.cpp:86
std::string name() const
Definition x931_rng.cpp:124
void encrypt(const byte in[], byte out[]) const
virtual size_t block_size() const =0
size_t size() const
Definition secmem.h:29
void resize(size_t n)
Definition secmem.h:217
virtual bool is_seeded() const
Definition rng.h:57
SecureVector< byte > random_vec(size_t bytes)
Definition rng.h:40
virtual void randomize(byte output[], size_t length)=0
void set_key(const SymmetricKey &key)
Definition sym_algo.h:60
size_t maximum_keylength() const
Definition sym_algo.h:33
void zeroise(MemoryRegion< T > &vec)
Definition secmem.h:428
void xor_buf(byte out[], const byte in[], size_t length)
Definition xor_buf.h:21
void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:22
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
PRNG_Unseeded(const std::string &algo)
Definition exceptn.h:91