LibHac/tests/LibHac.Tests/CryptoTests/RspReader.cs

220 lines
6.4 KiB
C#
Raw Normal View History

2019-11-09 08:32:13 +01:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using LibHac.Util;
2019-11-09 08:32:13 +01:00
using Xunit;
2021-11-14 20:08:57 +01:00
namespace LibHac.Tests.CryptoTests;
public class RspReader
2019-11-09 08:32:13 +01:00
{
2021-11-14 20:08:57 +01:00
private StreamReader Reader { get; }
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
public RspReader(Stream stream)
{
Reader = new StreamReader(stream);
}
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
public IEnumerable<EncryptionTestVector> GetEncryptionTestVectors()
{
string line;
bool isEncryptType = false;
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
var testVector = new EncryptionTestVector();
bool canOutputVector = false;
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
while ((line = Reader.ReadLine()?.Trim()) != null)
{
if (line.Length == 0)
2019-11-09 08:32:13 +01:00
{
2021-11-14 20:08:57 +01:00
if (canOutputVector)
2019-11-09 08:32:13 +01:00
{
2021-11-14 20:08:57 +01:00
testVector.Encrypt = isEncryptType;
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
yield return testVector;
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
testVector = new EncryptionTestVector();
canOutputVector = false;
2019-11-09 08:32:13 +01:00
}
2021-11-14 20:08:57 +01:00
continue;
}
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
if (line[0] == '#') continue;
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
if (line[0] == '[')
{
if (line == "[ENCRYPT]") isEncryptType = true;
if (line == "[DECRYPT]") isEncryptType = false;
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
continue;
}
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
string[] kvp = line.Split(new[] { " = " }, StringSplitOptions.None);
if (kvp.Length != 2) throw new InvalidDataException();
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
canOutputVector = true;
switch (kvp[0].ToUpperInvariant())
{
case "COUNT":
testVector.Count = int.Parse(kvp[1]);
break;
case "DATAUNITLEN":
testVector.DataUnitLength = int.Parse(kvp[1]);
break;
case "KEY":
testVector.Key = kvp[1].ToBytes();
break;
case "IV":
case "I":
testVector.Iv = kvp[1].ToBytes();
break;
case "PLAINTEXT":
case "PT":
testVector.PlainText = kvp[1].ToBytes();
break;
case "CIPHERTEXT":
case "CT":
testVector.CipherText = kvp[1].ToBytes();
break;
2019-11-09 08:32:13 +01:00
}
}
2021-11-14 20:08:57 +01:00
}
public static TheoryData<EncryptionTestVector> ReadEncryptionTestVectors(bool getEncryptTests, params string[] filenames)
{
EncryptionTestVector[] vectorArray = ReadEncryptionTestVectorsArray(getEncryptTests, filenames);
var testVectors = new TheoryData<EncryptionTestVector>();
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
foreach (EncryptionTestVector test in vectorArray)
2019-11-09 08:32:13 +01:00
{
2021-11-14 20:08:57 +01:00
testVectors.Add(test);
}
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
return testVectors;
}
2021-11-14 20:08:57 +01:00
public static EncryptionTestVector[] ReadEncryptionTestVectorsArray(bool getEncryptTests, params string[] filenames)
{
IEnumerable<string> resourcePaths = filenames.Select(x => $"LibHac.Tests.CryptoTests.TestVectors.{x}");
var testVectors = new List<EncryptionTestVector>();
2021-11-14 20:08:57 +01:00
foreach (string path in resourcePaths)
{
2021-11-14 20:08:57 +01:00
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path))
2019-11-09 08:32:13 +01:00
{
2021-11-14 20:08:57 +01:00
var reader = new RspReader(stream);
2019-11-09 08:32:13 +01:00
2021-11-14 20:08:57 +01:00
foreach (EncryptionTestVector tv in reader.GetEncryptionTestVectors().Where(x => x.Encrypt == getEncryptTests))
{
testVectors.Add(tv);
2019-11-09 08:32:13 +01:00
}
}
2019-11-25 21:11:40 +01:00
}
2021-11-14 20:08:57 +01:00
return testVectors.ToArray();
}
public IEnumerable<HashTestVector> GetHashTestVectors()
{
string line;
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
var testVector = new HashTestVector();
bool canOutputVector = false;
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
while ((line = Reader.ReadLine()?.Trim()) != null)
{
if (line.Length == 0)
2019-11-25 21:11:40 +01:00
{
2021-11-14 20:08:57 +01:00
if (canOutputVector)
2019-11-25 21:11:40 +01:00
{
2021-11-14 20:08:57 +01:00
yield return testVector;
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
testVector = new HashTestVector();
canOutputVector = false;
2019-11-25 21:11:40 +01:00
}
2021-11-14 20:08:57 +01:00
continue;
}
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
if (line[0] == '#') continue;
if (line[0] == '[') continue;
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
string[] kvp = line.Split(new[] { " = " }, StringSplitOptions.None);
if (kvp.Length != 2) throw new InvalidDataException();
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
canOutputVector = true;
switch (kvp[0].ToUpperInvariant())
{
case "LEN":
testVector.LengthBits = int.Parse(kvp[1]);
testVector.LengthBytes = testVector.LengthBits / 8;
break;
case "MSG":
testVector.Message = kvp[1].ToBytes();
break;
case "MD":
testVector.Digest = kvp[1].ToBytes();
break;
2019-11-25 21:11:40 +01:00
}
}
2021-11-14 20:08:57 +01:00
}
public static TheoryData<HashTestVector> ReadHashTestVectors(params string[] filenames)
{
HashTestVector[] vectorArray = ReadHashTestVectorsArray(filenames);
var testVectors = new TheoryData<HashTestVector>();
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
foreach (HashTestVector test in vectorArray)
2019-11-25 21:11:40 +01:00
{
2021-11-14 20:08:57 +01:00
testVectors.Add(test);
}
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
return testVectors;
}
2021-11-14 20:08:57 +01:00
public static HashTestVector[] ReadHashTestVectorsArray(params string[] filenames)
{
IEnumerable<string> resourcePaths = filenames.Select(x => $"LibHac.Tests.CryptoTests.TestVectors.{x}");
var testVectors = new List<HashTestVector>();
2021-11-14 20:08:57 +01:00
foreach (string path in resourcePaths)
{
2021-11-14 20:08:57 +01:00
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path))
2019-11-25 21:11:40 +01:00
{
2021-11-14 20:08:57 +01:00
var reader = new RspReader(stream);
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
foreach (HashTestVector tv in reader.GetHashTestVectors())
{
testVectors.Add(tv);
2019-11-25 21:11:40 +01:00
}
}
2019-11-09 08:32:13 +01:00
}
2021-11-14 20:08:57 +01:00
return testVectors.ToArray();
2019-11-09 08:32:13 +01:00
}
2021-11-14 20:08:57 +01:00
}
2019-11-25 21:11:40 +01:00
2021-11-14 20:08:57 +01:00
public class EncryptionTestVector
{
public bool Encrypt { get; set; }
public int Count { get; set; }
public int DataUnitLength { get; set; }
public byte[] Key { get; set; }
public byte[] Iv { get; set; }
public byte[] PlainText { get; set; }
public byte[] CipherText { get; set; }
}
public class HashTestVector
{
public int LengthBits { get; set; }
public int LengthBytes { get; set; }
public byte[] Message { get; set; }
public byte[] Digest { get; set; }
2019-11-09 08:32:13 +01:00
}