1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
using System;
using Org.BouncyCastle.Crypto.Prng.Drbg;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Prng
{
public class SP800SecureRandom
: SecureRandom
{
private readonly IDrbgProvider mDrbgProvider;
private readonly bool mPredictionResistant;
private readonly SecureRandom mRandomSource;
private readonly IEntropySource mEntropySource;
private ISP80090Drbg mDrbg;
internal SP800SecureRandom(SecureRandom randomSource, IEntropySource entropySource, IDrbgProvider drbgProvider,
bool predictionResistant)
: base(null)
{
this.mRandomSource = randomSource;
this.mEntropySource = entropySource;
this.mDrbgProvider = drbgProvider;
this.mPredictionResistant = predictionResistant;
}
public override void SetSeed(byte[] seed)
{
lock (this)
{
if (mRandomSource != null)
{
this.mRandomSource.SetSeed(seed);
}
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
public override void SetSeed(Span<byte> seed)
{
lock (this)
{
if (mRandomSource != null)
{
this.mRandomSource.SetSeed(seed);
}
}
}
#endif
public override void SetSeed(long seed)
{
lock (this)
{
// this will happen when SecureRandom() is created
if (mRandomSource != null)
{
this.mRandomSource.SetSeed(seed);
}
}
}
public override void NextBytes(byte[] bytes)
{
NextBytes(bytes, 0, bytes.Length);
}
public override void NextBytes(byte[] buf, int off, int len)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
NextBytes(buf.AsSpan(off, len));
#else
lock (this)
{
if (mDrbg == null)
{
mDrbg = mDrbgProvider.Get(mEntropySource);
}
// check if a reseed is required...
if (mDrbg.Generate(buf, off, len, null, mPredictionResistant) < 0)
{
mDrbg.Reseed(null);
mDrbg.Generate(buf, off, len, null, mPredictionResistant);
}
}
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
public override void NextBytes(Span<byte> buffer)
{
lock (this)
{
if (mDrbg == null)
{
mDrbg = mDrbgProvider.Get(mEntropySource);
}
// check if a reseed is required...
if (mDrbg.Generate(buffer, mPredictionResistant) < 0)
{
mDrbg.Reseed(ReadOnlySpan<byte>.Empty);
mDrbg.Generate(buffer, mPredictionResistant);
}
}
}
#endif
public override byte[] GenerateSeed(int numBytes)
{
return EntropyUtilities.GenerateSeed(mEntropySource, numBytes);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
public override void GenerateSeed(Span<byte> seed)
{
EntropyUtilities.GenerateSeed(mEntropySource, seed);
}
#endif
/// <summary>Force a reseed of the DRBG.</summary>
/// <param name="additionalInput">optional additional input</param>
public virtual void Reseed(byte[] additionalInput)
{
lock (this)
{
if (mDrbg == null)
{
mDrbg = mDrbgProvider.Get(mEntropySource);
}
mDrbg.Reseed(additionalInput);
}
}
}
}
|