1 //
2 // Copyright (c) 2010-2022 Antmicro
3 //
4 //  This file is licensed under the MIT License.
5 //  Full license text is available in 'licenses/MIT.txt'.
6 //
7 using Antmicro.Renode.Core;
8 using Antmicro.Renode.Logging;
9 
10 namespace Antmicro.Renode.Peripherals.Miscellaneous.Crypto
11 {
12     // This class exposes the functionality of the DRBG core (short for "Deterministic Random Bit Generator"),
13     // but because it is simplified, the name is also changed to be more adequate.
14     public class PseudorandomBitGenerator
15     {
PseudorandomBitGenerator(InternalMemoryManager manager)16         public PseudorandomBitGenerator(InternalMemoryManager manager)
17         {
18             this.manager = manager;
19             Reset();
20         }
21 
Generate()22         public void Generate()
23         {
24             manager.TryReadDoubleWord((long)DRBGRegisters.EntropyFactor, out reqLen);
25             manager.TryReadDoubleWord((long)DRBGRegisters.ReseedLimit, out var reseedLimit);
26             if(reseedLimit == 1 || reseedCounter == 0)
27             {
28                 Reseed(reseedLimit);
29             }
30             for(var i = 0; i < reqLen * 4; ++i)
31             {
32                 manager.TryWriteDoubleWord(
33                     (long)DRBGRegisters.ResponseDataAddress + (i * 4),
34                     (uint)EmulationManager.Instance.CurrentEmulation.RandomGenerator.Next()
35                 );
36             }
37             if(reseedCounter >= 0)
38             {
39                 reseedCounter--;
40             }
41         }
42 
Reset()43         public void Reset()
44         {
45             reseedCounter = 0;
46             reqLen = 0;
47         }
48 
Reseed(uint limit)49         private void Reseed(uint limit)
50         {
51             Logger.Log(LogLevel.Noisy, "Requested seed reset.");
52             // As a simplification, and to ensure execution determinism, we increment the existing seed by one.
53             EmulationManager.Instance.CurrentEmulation.RandomGenerator.ResetSeed(
54                 EmulationManager.Instance.CurrentEmulation.RandomGenerator.GetCurrentSeed() + 1
55             );
56             reseedCounter = limit;
57         }
58 
59         private uint reseedCounter;
60         private uint reqLen;
61 
62         private readonly InternalMemoryManager manager;
63 
64         private enum DRBGRegisters
65         {
66             EntropyFactor = 0x8,
67             KeyOrdinal = 0xC,
68             ReseedLimit = 0x10,
69             IsTestInstantiation = 0x14,
70             AdditionalInputDataLength = 0x18,
71             PersonalizationStringAddress = 0x1C,
72             ContextAddress = 0x20,
73             AdditionalInputDataAddress = 0x188,
74             ResponseDataAddress = 0x8090,
75         }
76     }
77 }
78