~zooko/cryptopp/trunk

« back to all changes in this revision

Viewing changes to rng.cpp

  • Committer: weidai
  • Date: 2007-05-04 15:04:58 UTC
  • Revision ID: svn-v4:57ff6487-cd31-0410-9ec3-f628ee90f5f0:trunk/c5:328
reduce risk of random number reuse after VM rollback

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
#include "pch.h"
4
4
 
5
5
#include "rng.h"
 
6
#include "fips140.h"
6
7
 
7
8
#include <time.h>
8
9
#include <math.h>
35
36
const word16 LC_RNG::r=2836;
36
37
#endif
37
38
 
38
 
byte LC_RNG::GenerateByte()
 
39
void LC_RNG::GenerateBlock(byte *output, size_t size)
39
40
{
40
 
        word32 hi = seed/q;
41
 
        word32 lo = seed%q;
42
 
 
43
 
        long test = a*lo - r*hi;
44
 
 
45
 
        if (test > 0)
46
 
                seed = test;
47
 
        else
48
 
                seed = test+ m;
49
 
 
50
 
        return (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3));
 
41
        while (size--)
 
42
        {
 
43
                word32 hi = seed/q;
 
44
                word32 lo = seed%q;
 
45
 
 
46
                long test = a*lo - r*hi;
 
47
 
 
48
                if (test > 0)
 
49
                        seed = test;
 
50
                else
 
51
                        seed = test+ m;
 
52
 
 
53
                *output++ = (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3));
 
54
        }
51
55
}
52
56
 
53
57
// ********************************************************
59
63
          S(cipher->BlockSize()),
60
64
          dtbuf(S),
61
65
          randseed(seed, S),
62
 
          randbuf(S),
63
 
          randbuf_counter(0),
 
66
          m_lastBlock(S),
64
67
          m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? S : 0)
65
68
{
66
69
        if (!deterministicTimeVector)
67
70
        {
68
71
                time_t tstamp1 = time(0);
69
 
                xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S));
 
72
                xorbuf(dtbuf, (byte *)&tstamp1, UnsignedMin(sizeof(tstamp1), S));
70
73
                cipher->ProcessBlock(dtbuf);
71
74
                clock_t tstamp2 = clock();
72
 
                xorbuf(dtbuf, (byte *)&tstamp2, STDMIN((int)sizeof(tstamp2), S));
 
75
                xorbuf(dtbuf, (byte *)&tstamp2, UnsignedMin(sizeof(tstamp2), S));
73
76
                cipher->ProcessBlock(dtbuf);
74
77
        }
 
78
 
 
79
        // for FIPS 140-2
 
80
        GenerateBlock(m_lastBlock, S);
75
81
}
76
82
 
77
 
byte X917RNG::GenerateByte()
 
83
void X917RNG::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size)
78
84
{
79
 
        if (randbuf_counter==0)
 
85
        while (size > 0)
80
86
        {
81
87
                // calculate new enciphered timestamp
82
88
                if (m_deterministicTimeVector.size())
86
92
                }
87
93
                else
88
94
                {
89
 
                        clock_t tstamp = clock();
90
 
                        xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S));
 
95
                        clock_t c = clock();
 
96
                        xorbuf(dtbuf, (byte *)&c, UnsignedMin(sizeof(c), S));
 
97
                        time_t t = time(NULL);
 
98
                        xorbuf(dtbuf+S-UnsignedMin(sizeof(t), S), (byte *)&t, UnsignedMin(sizeof(t), S));
91
99
                        cipher->ProcessBlock(dtbuf);
92
100
                }
93
101
 
95
103
                xorbuf(randseed, dtbuf, S);
96
104
 
97
105
                // generate a new block of random bytes
98
 
                cipher->ProcessBlock(randseed, randbuf);
 
106
                cipher->ProcessBlock(randseed);
 
107
                if (memcmp(m_lastBlock, randseed, S) == 0)
 
108
                        throw SelfTestFailure("X917RNG: Continuous random number generator test failed.");
 
109
 
 
110
                // output random bytes
 
111
                size_t len = UnsignedMin(size, S);
 
112
                target.ChannelPut(channel, randseed, len);
 
113
                size -= len;
99
114
 
100
115
                // compute new seed vector
101
 
                for (int i=0; i<S; i++)
102
 
                        randseed[i] = randbuf[i] ^ dtbuf[i];
 
116
                memcpy(m_lastBlock, randseed, S);
 
117
                xorbuf(randseed, dtbuf, S);
103
118
                cipher->ProcessBlock(randseed);
104
 
 
105
 
                randbuf_counter=S;
106
119
        }
107
 
        return(randbuf[S-randbuf_counter--]);
108
120
}
109
121
 
110
122
#endif