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 System;
8 using NUnit.Framework;
9 using Antmicro.Renode.Core;
10 using Antmicro.Renode.Peripherals.Memory;
11 using Antmicro.Renode.Peripherals.MemoryControllers;
12 using Antmicro.Renode.Peripherals.Miscellaneous;
13 
14 namespace Antmicro.Renode.PeripheralsTests
15 {
16     [TestFixture]
17     public class OpenTitan_KeyManagerTest
18     {
19         [SetUp]
Setup()20         public void Setup()
21         {
22             this.machine = new Machine();
23             var rom = new MappedMemory(machine, 0x100);
24             var rom_ctrl = new OpenTitan_ROMController(rom, "0000000000000000", "0000000000000000");
25             this.peripheral = new OpenTitan_KeyManager(machine, rom_ctrl,
26                 deviceId: "fa53b8058e157cb69f1f413e87242971b6b52a656a1cab7febf21e5bf1f45edd",
27                 lifeCycleDiversificationConstant: "6faf88f22bccd612d1c09f5c02b2c8d1",
28                 creatorKey: "9152e32c9380a4bcc3e0ab263581e6b0e8825186e1e445631646e8bef8c45d47",
29                 ownerKey: "fa365df52da48cd752fb3a026a8e608f0098cfe5fa9810494829d0cd9479eb78",
30                 rootKey: "efb7ea7ee90093cf4affd9aaa2d6c0ec446cfdf5f2d5a0bfd7e2d93edc63a10256d24a00181de99e0f690b447a8dde2a1ffb8bc306707107aa6e2410f15cfc37",
31                 softOutputSeed: "df273097a573a411332efd86009bd0a175f08814ecc17ab02cc1e3404e1cd8bf",
32                 hardOutputSeed: "69582e71443c8be0fc00de9d9734c3fe7f4266d10a752de74814f2a3079f69a3",
33                 destinationNoneSeed: "73e5bc251b143b74476e576754125d61930d203f199a87c123c074e020fd5028",
34                 destinationAesSeed: "ce44cbff5e09e6dd3ae54e9e45da6e662fb69c3aab936b415a0d6e7185eaa2e0",
35                 destinationOtbnSeed: "fcc581b66ae11d33f678e7d227881bcfe58a331208f189de6265edc8fde06db0",
36                 destinationKmacSeed: "b76a8aff9e4da0e3ff9f3036fd9c13ac08496db56fbc4894d38bd8674f4b542d",
37                 revisionSeed: "17a9838dd4cd7f1bdce673b937a6d75202fedbf893bf7d52c8a744ad83d2630b",
38                 creatorIdentitySeed: "c20c05a20251023541544776930be76bfbb22e1d8aaa4783f2b5e094e3e8d3f8",
39                 ownerIntermediateIdentitySeed: "93cdb1d9a6a60050ef0d8a166d91200dc6757907237df4401908799dfa1fe8f2",
40                 ownerIdentitySeed: "a88601ca1695a7c8c5d32486aac4e086628d6c8ca138f65d25dfa5f9c912f354"
41             );
42         }
43 
44         [Test]
ShouldInitToResetState()45         public void ShouldInitToResetState()
46         {
47             Assert.AreEqual(OpenTitan_KeyManager.WorkingState.Reset, GetWorkingState());
48         }
49 
50         [Test]
ShouldAdvanceStateProperly()51         public void ShouldAdvanceStateProperly()
52         {
53             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
54             Assert.AreEqual(OpenTitan_KeyManager.WorkingState.Init, GetWorkingState());
55             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
56             Assert.AreEqual(OpenTitan_KeyManager.WorkingState.CreatorRootKey, GetWorkingState());
57             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
58             Assert.AreEqual(OpenTitan_KeyManager.WorkingState.OwnerIntermediateKey, GetWorkingState());
59             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
60             Assert.AreEqual(OpenTitan_KeyManager.WorkingState.OwnerKey, GetWorkingState());
61             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
62             Assert.AreEqual(OpenTitan_KeyManager.WorkingState.Disabled, GetWorkingState());
63             // Should not advance from `Disabled`
64             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
65             Assert.AreEqual(OpenTitan_KeyManager.WorkingState.Disabled, GetWorkingState());
66         }
67 
68         [Test]
ShouldIgnoreOtherCommandsInResetState()69         public void ShouldIgnoreOtherCommandsInResetState()
70         {
71             peripheral.Reset();
72             Disable();
73             AssertErrorIsRaised(false);
74             SendCommand(OpenTitan_KeyManager.OperationMode.GenerateID);
75             AssertErrorIsRaised(false);
76         }
77 
78         [Test]
ShouldClearErrorsAfterValidOperation()79         public void ShouldClearErrorsAfterValidOperation()
80         {
81             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
82             SendCommand(OpenTitan_KeyManager.OperationMode.GenerateID);
83             AssertErrorIsRaised(true, "GenerateID in Init state");
84             // Clear Errors
85             peripheral.WriteDoubleWord((long)OpenTitan_KeyManager.Registers.ErrorCode, 0x7);
86             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
87             AssertErrorIsRaised(false, "Advance in Init state");
88         }
89 
90         [Test]
ShouldRaiseErrorOnIllegalCommand()91         public void ShouldRaiseErrorOnIllegalCommand()
92         {
93             peripheral.Reset();
94             //Init
95             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
96 
97             SendCommand(OpenTitan_KeyManager.OperationMode.GenerateID);
98             AssertErrorIsRaised(true, $"{OpenTitan_KeyManager.OperationMode.GenerateID} in Init state");
99             SendCommand(OpenTitan_KeyManager.OperationMode.GenerateSWOutput);
100             AssertErrorIsRaised(true, $"{OpenTitan_KeyManager.OperationMode.GenerateSWOutput} in Init state");
101             SendCommand(OpenTitan_KeyManager.OperationMode.GenerateHWOutput);
102             AssertErrorIsRaised(true, $"{OpenTitan_KeyManager.OperationMode.GenerateHWOutput} in Init state");
103 
104             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
105             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
106             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
107             //Disabled
108             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
109 
110             SendCommand(OpenTitan_KeyManager.OperationMode.Advance);
111             AssertErrorIsRaised(true, $"{OpenTitan_KeyManager.OperationMode.Advance} in Disabled state");
112             SendCommand(OpenTitan_KeyManager.OperationMode.Disable);
113             AssertErrorIsRaised(true, $"{OpenTitan_KeyManager.OperationMode.Disable} in Disabled state");
114             SendCommand(OpenTitan_KeyManager.OperationMode.GenerateID);
115             AssertErrorIsRaised(true, $"{OpenTitan_KeyManager.OperationMode.GenerateID} in Disabled state");
116             SendCommand(OpenTitan_KeyManager.OperationMode.GenerateSWOutput);
117             AssertErrorIsRaised(true, $"{OpenTitan_KeyManager.OperationMode.GenerateSWOutput} in Disabled state");
118             SendCommand(OpenTitan_KeyManager.OperationMode.GenerateHWOutput);
119             AssertErrorIsRaised(true, $"{OpenTitan_KeyManager.OperationMode.GenerateHWOutput} in Disabled state");
120         }
121 
SendCommand(OpenTitan_KeyManager.OperationMode command)122         private void SendCommand(OpenTitan_KeyManager.OperationMode command)
123         {
124             peripheral.WriteDoubleWord((long)OpenTitan_KeyManager.Registers.OperationControls, (((uint)command) << 4 | 0x1));
125         }
126 
Disable()127         private void Disable()
128         {
129             SendCommand(OpenTitan_KeyManager.OperationMode.Disable);
130         }
131 
GetWorkingState()132         private OpenTitan_KeyManager.WorkingState GetWorkingState()
133         {
134             return (OpenTitan_KeyManager.WorkingState)peripheral.ReadDoubleWord((long)OpenTitan_KeyManager.Registers.WorkingState);
135         }
136 
AssertErrorIsRaised(bool errorExpected, string message = R)137         private void AssertErrorIsRaised(bool errorExpected, string message = "")
138         {
139             if(errorExpected)
140             {
141                 Assert.AreNotEqual(0x0, ReadError(), message);
142                 Assert.AreEqual(0x3 , ReadStatus(), message);
143             }
144             else
145             {
146                 Assert.AreEqual(0x0, ReadError(), message);
147                 Assert.AreNotEqual(0x3 , ReadStatus(), message);
148             }
149         }
150 
ReadError()151         private uint ReadError()
152         {
153             return peripheral.ReadDoubleWord((long)OpenTitan_KeyManager.Registers.ErrorCode);
154         }
155 
ReadStatus()156         private uint ReadStatus()
157         {
158             return peripheral.ReadDoubleWord((long)OpenTitan_KeyManager.Registers.Status);
159         }
160 
161         private IMachine machine;
162         private OpenTitan_KeyManager peripheral;
163     }
164 }
165