📄 fipsalgt.cpp
字号:
if (m_mode == "ECB")
{
if (encrypt)
{
IB[j] = PT[j];
CT[j].resize(blockSize);
pBT->ProcessBlock(IB[j], CT[j]);
PT[j+1] = CT[j];
}
else
{
IB[j] = CT[j];
PT[j].resize(blockSize);
pBT->ProcessBlock(IB[j], PT[j]);
CT[j+1] = PT[j];
}
}
else if (m_mode == "OFB")
{
OB[j].resize(blockSize);
pBT->ProcessBlock(IB[j], OB[j]);
Xor(RESULT[j], OB[j], TXT[j]);
TXT[j+1] = IB[j];
IB[j+1] = OB[j];
}
else if (m_mode == "CBC")
{
if (encrypt)
{
Xor(IB[j], PT[j], CV[j]);
CT[j].resize(blockSize);
pBT->ProcessBlock(IB[j], CT[j]);
PT[j+1] = CV[j];
CV[j+1] = CT[j];
}
else
{
IB[j] = CT[j];
OB[j].resize(blockSize);
pBT->ProcessBlock(IB[j], OB[j]);
Xor(PT[j], OB[j], CV[j]);
CV[j+1] = CT[j];
CT[j+1] = PT[j];
}
}
else if (m_mode == "CFB")
{
if (encrypt)
{
OB[j].resize(blockSize);
pBT->ProcessBlock(IB[j], OB[j]);
AssignLeftMostBits(CT[j], OB[j], K);
Xor(CT[j], CT[j], PT[j]);
AssignLeftMostBits(PT[j+1], IB[j], K);
IB[j+1].resize(blockSize);
memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
}
else
{
OB[j].resize(blockSize);
pBT->ProcessBlock(IB[j], OB[j]);
AssignLeftMostBits(PT[j], OB[j], K);
Xor(PT[j], PT[j], CT[j]);
IB[j+1].resize(blockSize);
memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
AssignLeftMostBits(CT[j+1], OB[j], K);
}
}
else
throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
}
OutputData(output, COUNT, IntToString(i));
OutputData(output, KEY_T, KEY[i]);
if (m_mode == "CBC")
OutputData(output, IV, CV[0]);
if (m_mode == "OFB" || m_mode == "CFB")
OutputData(output, IV, IB[0]);
if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB")
{
if (encrypt)
{
OutputData(output, INPUT, PT[0]);
OutputData(output, OUTPUT, CT[innerCount-1]);
KEY[i+1] = UpdateKey(KEY[i], &CT[0]);
}
else
{
OutputData(output, INPUT, CT[0]);
OutputData(output, OUTPUT, PT[innerCount-1]);
KEY[i+1] = UpdateKey(KEY[i], &PT[0]);
}
PT[0] = PT[innerCount];
IB[0] = IB[innerCount];
CV[0] = CV[innerCount];
CT[0] = CT[innerCount];
}
else if (m_mode == "OFB")
{
OutputData(output, INPUT, TXT[0]);
OutputData(output, OUTPUT, RESULT[innerCount-1]);
KEY[i+1] = UpdateKey(KEY[i], &RESULT[0]);
Xor(TXT[0], TXT[0], IB[innerCount-1]);
IB[0] = OB[innerCount-1];
}
output += "\n";
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
}
else if (m_test == "MCT")
{
SecByteBlock KEY[101];
KEY[0] = key;
int keySize = key.size();
int blockSize = pBT->BlockSize();
SecByteBlock ivs[101], inputs[1001], outputs[1001];
ivs[0] = iv;
inputs[0] = m_data2[INPUT];
for (int i=0; i<100; i++)
{
pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8, false));
for (int j=0; j<1000; j++)
{
outputs[j] = inputs[j];
pCipher->ProcessString(outputs[j], outputs[j].size());
if (K==8 && m_mode == "CFB")
{
if (j<16)
inputs[j+1].Assign(ivs[i]+j, 1);
else
inputs[j+1] = outputs[j-16];
}
else if (m_mode == "ECB")
inputs[j+1] = outputs[j];
else if (j == 0)
inputs[j+1] = ivs[i];
else
inputs[j+1] = outputs[j-1];
}
if (m_algorithm == "AES")
OutputData(output, COUNT, m_count++);
OutputData(output, KEY_T, KEY[i]);
if (m_mode != "ECB")
OutputData(output, IV, ivs[i]);
OutputData(output, INPUT, inputs[0]);
OutputData(output, OUTPUT, outputs[999]);
output += "\n";
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
KEY[i+1] = UpdateKey(KEY[i], outputs);
ivs[i+1].CleanNew(pCipher->IVSize());
ivs[i+1] = UpdateKey(ivs[i+1], outputs);
if (K==8 && m_mode == "CFB")
inputs[0] = outputs[999-16];
else if (m_mode == "ECB")
inputs[0] = outputs[999];
else
inputs[0] = outputs[998];
}
}
else
{
assert(m_test == "KAT");
SecByteBlock &input = m_data2[INPUT];
SecByteBlock result(input.size());
member_ptr<Filter> pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING));
StringSource(input.data(), input.size(), true, pFilter.release());
OutputGivenData(output, COUNT, true);
OutputData(output, KEY_T, key);
OutputGivenData(output, IV, true);
OutputGivenData(output, INPUT);
OutputData(output, OUTPUT, result);
output += "\n";
AttachedTransformation()->Put((byte *)output.data(), output.size());
}
}
std::vector<std::string> Tokenize(const std::string &line)
{
std::vector<std::string> result;
std::string s;
for (unsigned int i=0; i<line.size(); i++)
{
if (isalnum(line[i]) || line[i] == '^')
s += line[i];
else if (!s.empty())
{
result.push_back(s);
s = "";
}
if (line[i] == '=')
result.push_back("=");
}
if (!s.empty())
result.push_back(s);
return result;
}
bool IsolatedMessageEnd(bool blocking)
{
if (!blocking)
throw BlockingInputOnly("TestDataParser");
m_line.resize(0);
m_inQueue.TransferTo(StringSink(m_line).Ref());
if (m_line[0] == '#')
return false;
bool copyLine = false;
if (m_line[0] == '[')
{
m_bracketString = m_line.substr(1, m_line.size()-2);
if (m_bracketString == "ENCRYPT")
SetEncrypt(true);
if (m_bracketString == "DECRYPT")
SetEncrypt(false);
copyLine = true;
}
if (m_line.substr(0, 2) == "H>")
{
assert(m_test == "sha");
m_bracketString = m_line.substr(2, m_line.size()-4);
m_line = m_line.substr(0, 13) + "Hashes<H";
copyLine = true;
}
if (m_line == "D>")
copyLine = true;
if (m_line == "<D")
{
m_line += "\n";
copyLine = true;
}
if (copyLine)
{
m_line += '\n';
AttachedTransformation()->Put((byte *)m_line.data(), m_line.size(), blocking);
return false;
}
std::vector<std::string> tokens = Tokenize(m_line);
if (m_algorithm == "DSA" && m_test == "sha")
{
for (unsigned int i = 0; i < tokens.size(); i++)
{
if (tokens[i] == "^")
DoTest();
else if (tokens[i] != "")
m_compactString.push_back(atol(tokens[i].c_str()));
}
}
else
{
if (!m_line.empty() && ((m_algorithm == "RSA" && m_test != "Gen") || m_algorithm == "RNG" || m_algorithm == "HMAC" || m_algorithm == "SHA" || (m_algorithm == "ECDSA" && m_test != "KeyPair") || (m_algorithm == "DSA" && (m_test == "PQGVer" || m_test == "SigVer"))))
{
// copy input to output
std::string output = m_line + '\n';
AttachedTransformation()->Put((byte *)output.data(), output.size());
}
for (unsigned int i = 0; i < tokens.size(); i++)
{
if (m_firstLine && m_algorithm != "DSA")
{
if (tokens[i] == "Encrypt" || tokens[i] == "OFB")
SetEncrypt(true);
else if (tokens[i] == "Decrypt")
SetEncrypt(false);
else if (tokens[i] == "Modes")
m_test = "MONTE";
}
else
{
if (tokens[i] != "=")
continue;
if (i == 0)
throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line);
const std::string &key = tokens[i-1];
std::string &data = m_data[key];
data = (tokens.size() > i+1) ? tokens[i+1] : "";
DataType t = m_nameToType[key];
m_typeToName[t] = key;
m_data2[t] = DecodeHex(data);
if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty() && !isspace(m_line[0])))
DoTest();
}
}
}
m_firstLine = false;
return false;
}
inline const SecByteBlock & GetData(const std::string &key)
{
return m_data2[m_nameToType[key]];
}
static SecByteBlock DecodeHex(const std::string &data)
{
SecByteBlock data2(data.size() / 2);
StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size())));
return data2;
}
std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger;
unsigned int m_feedbackSize, m_blankLineTransition;
bool m_encrypt, m_firstLine;
typedef std::map<std::string, DataType> NameToTypeMap;
NameToTypeMap m_nameToType;
typedef std::map<DataType, std::string> TypeToNameMap;
TypeToNameMap m_typeToName;
typedef std::map<std::string, std::string> Map;
Map m_data; // raw data
typedef std::map<DataType, SecByteBlock> Map2;
Map2 m_data2;
int m_count;
AutoSeededX917RNG<AES> m_rng;
std::vector<unsigned int> m_compactString;
};
int FIPS_140_AlgorithmTest(int argc, char **argv)
{
argc--;
argv++;
std::string algorithm = argv[1];
std::string pathname = argv[2];
unsigned int i = pathname.find_last_of("\\/");
std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1);
std::string dirname = pathname.substr(0, i);
if (algorithm == "auto")
{
string algTable[] = {"AES", "ECDSA", "DSA", "HMAC", "RNG", "RSA", "TDES", "SKIPJACK", "SHA"}; // order is important here
for (i=0; i<sizeof(algTable)/sizeof(algTable[0]); i++)
{
if (dirname.find(algTable[i]) != std::string::npos)
{
algorithm = algTable[i];
break;
}
}
}
try
{
std::string mode;
if (algorithm == "SHA")
mode = IntToString(atol(filename.substr(3, 3).c_str()));
else if (algorithm == "RSA")
mode = filename.substr(6, 1);
else if (filename[0] == 'S' || filename[0] == 'T')
mode = filename.substr(1, 3);
else
mode = filename.substr(0, 3);
for (i = 0; i<mode.size(); i++)
mode[i] = toupper(mode[i]);
unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0;
std::string test;
if (algorithm == "DSA" || algorithm == "ECDSA")
test = filename.substr(0, filename.size() - 4);
else if (algorithm == "RSA")
test = filename.substr(3, 3);
else if (filename.find("Monte") != std::string::npos)
test = "MONTE";
else if (filename.find("MCT") != std::string::npos)
test = "MCT";
else
test = "KAT";
bool encrypt = (filename.find("vrct") == std::string::npos);
BufferedTransformation *pSink = NULL;
if (argc > 3)
{
std::string outDir = argv[3];
if (outDir == "auto")
{
if (dirname.substr(dirname.size()-3) == "req")
outDir = dirname.substr(0, dirname.size()-3) + "resp";
}
if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/')
outDir += '/';
std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp";
pSink = new FileSink(outPathname.c_str(), false);
}
else
pSink = new FileSink(cout);
FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false);
}
catch (...)
{
cout << "file: " << filename << endl;
throw;
}
return 0;
}
extern int (*AdhocTest)(int argc, char *argv[]);
static int s_i = (AdhocTest = &FIPS_140_AlgorithmTest, 0);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -