1 // 2 // Copyright (c) 2010-2023 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.Logging; 8 using Antmicro.Renode.Peripherals.Bus; 9 using System; 10 using System.Linq; 11 using System.Numerics; 12 using System.Security.Cryptography; 13 14 namespace Antmicro.Renode.Peripherals.Miscellaneous.Crypto 15 { 16 public class DSAServiceProvider 17 { DSAServiceProvider(InternalMemoryManager manager, IBusController bus)18 public DSAServiceProvider(InternalMemoryManager manager, IBusController bus) 19 { 20 this.manager = manager; 21 this.bus = bus; 22 } 23 SignDMA()24 public void SignDMA() 25 { 26 // The driver is encoding data length as one doubleword: ((uiN<<16) | uiL)) 27 manager.TryReadDoubleWord((long)DSARegisters.DataLengthEncoded, out var dataLengthEncoded); 28 var uiL = dataLengthEncoded & 0xFFFF; 29 var uiN = dataLengthEncoded >> 16; 30 31 var g = AthenaX5200_BigIntegerHelper.CreateBigIntegerFromMemory(manager, (long)DSARegisters.G, uiL); 32 var k = AthenaX5200_BigIntegerHelper.CreateBigIntegerFromMemory(manager, (long)DSARegisters.K, uiN); 33 var p = AthenaX5200_BigIntegerHelper.CreateBigIntegerFromMemory(manager, (long)DSARegisters.P, uiL); 34 var q = AthenaX5200_BigIntegerHelper.CreateBigIntegerFromMemory(manager, (long)DSARegisters.Q, uiN); 35 var x = AthenaX5200_BigIntegerHelper.CreateBigIntegerFromMemory(manager, (long)DSARegisters.X, uiN); 36 37 // Step 1: 38 // r = (g^k mod p) mod q 39 var r = BigInteger.ModPow(g, k, p) % q; 40 var rBytes = r.ToByteArray(); 41 AthenaX5200_BigIntegerHelper.StoreBigIntegerBytes(manager, (uint)rBytes.Length, rBytes, (long)DSARegisters.R); 42 43 manager.TryReadDoubleWord((long)DSARegisters.MessageLenth, out var msgLength); 44 manager.TryReadDoubleWord((long)DSARegisters.MessageExternalAddress, out var msgExternalAddress); 45 var msgBytes = bus.ReadBytes(msgExternalAddress, (int)msgLength); 46 // We could use SHA384.HashData static method, but it's not available in Mono. 47 var hash = SHA384.Create().ComputeHash(msgBytes); 48 49 var z = AthenaX5200_BigIntegerHelper.CreateBigInteger(hash, Math.Min(q.ToByteArray().Length, hash.Length)); 50 51 // Step 2: 52 // s = (k^-1(z + xr)) mod q 53 var inverseK = AthenaX5200_BigIntegerHelper.CalculateModularInverse(k, q); 54 55 var S = (inverseK * (z + (x * r))) % q; 56 var sBytes = S.ToByteArray(); 57 AthenaX5200_BigIntegerHelper.StoreBigIntegerBytes(manager, (uint)sBytes.Length, sBytes, (long)DSARegisters.S); 58 } 59 60 private readonly IBusController bus; 61 private readonly InternalMemoryManager manager; 62 63 private enum DSARegisters 64 { 65 R = 0x20, 66 S = 0x40, 67 MessageLenth = 0x44, 68 MessageExternalAddress = 0x48, 69 G = 0x1348, 70 K = 0x14CC, 71 X = 0x14F0, 72 Q = 0x1000, 73 P = 0x1044, 74 DataLengthEncoded = 0x2410 75 } 76 } 77 } 78