Initial sshsm project structure
Issue-ID: AAF-94
Change-Id: I5e82fff418e7567b161acf9b98013a9b85ffc5b4
Signed-off-by: NingSun <ning.sun@intel.com>
diff --git a/SoftHSMv2/src/lib/crypto/test/AESTests.cpp b/SoftHSMv2/src/lib/crypto/test/AESTests.cpp
new file mode 100644
index 0000000..008560f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/AESTests.cpp
@@ -0,0 +1,1182 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AESTests.cpp
+
+ Contains test cases to test the AES implementation
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "AESTests.h"
+#include "CryptoFactory.h"
+#include "AESKey.h"
+#include <stdio.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(AESTests);
+
+void AESTests::setUp()
+{
+ aes = NULL;
+
+ aes = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::AES);
+
+ // Check the return value
+ CPPUNIT_ASSERT(aes != NULL);
+}
+
+void AESTests::tearDown()
+{
+ if (aes != NULL)
+ {
+ CryptoFactory::i()->recycleSymmetricAlgorithm(aes);
+ }
+
+ fflush(stdout);
+}
+
+void AESTests::testBlockSize()
+{
+ CPPUNIT_ASSERT(aes->getBlockSize() == 16);
+}
+
+void AESTests::testCBC()
+{
+ char testKeys128[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "89436760984679018453504364534464",
+ "49587346983643545706904580436731"
+ };
+
+ char testKeys192[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101213141516171819",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "096874395874290867409857496743857632098479834634",
+ "439867439058743095864395348375043296845094854983"
+ };
+
+ char testKeys256[][65] =
+ {
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20",
+ "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F",
+ "4394398576098257436095746985679043867498572406874967416846341641",
+ "4369006859867098670492857409386741095643756930847023587048579014"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "6CAEC72F5E101C66550215ACAB6B874C62E7BD074C0A09A8EE4562EFCB4E560A3E90FA0F50391087824FC27F57618E5C",
+ "E20E3123AC64FCA5536E0A2DC48DBEBCECB3F260EFF4A0EB99D72F57EF38DED336EB9DD0B968D24C91E63974E7445A21",
+ "C7910B1634DB493998608875A4652B20C64202ED507D9DBA06F62EB20A63C32FB6C9669D42A0AC29D773E6D40A63A2AC"
+ },
+ {
+ "8F48A65BF638FEDB7E6F59BAC8C110FEBA933F106D564119B88569E758B7FB83",
+ "125E1D93DC2C43A6FAFC508DB6F9A4A9F390D102C2300F0A3617CE95027BFAA3",
+ "FACB8DEF1B476400DE9796D5058E9086ECF04C927F5C160161C7A34D8288EB3C"
+ },
+ {
+ "C810E96482F109C9A05D2B1BEBAC7966BB7784F58A5478C1A07EC0DB39F6D87B",
+ "2385391BB8F2DD97280B1FAEFACB6B5C4FE12A2274D6B967509CF18500A640D6",
+ "47549520EADA1A5D931EACCC922F88BA2E386089BF97C790FD2CD38553334AE4"
+ },
+ {
+ "A7D9EAE80224624188CAA7012140E946",
+ "6ECD5C71ECA4AB9C3B71E91721CA2043",
+ "2F77AA438E9259F268985668B00650E5"
+ }
+ },
+ {
+ {
+ "FCB2FB6BF8ED8910F023A934EB9DA550E4D5B469D75B9390F4A207E54F29412450E52E980862DC80B89F6D1D10B68AA5",
+ "7EF0F65513CFE3E0D21305E2ECCBB3554B0DE119720C5A86337E57F74795BC23ED9CB82A951DE3D00D7A0DC8997319DD",
+ "5B83BFDB6EF3AEA5191F2EE3366EDE10480E9459C0DE2994DD9C6408A377DFFF8121A38CFD1AA864559B9A435A3BDD6D"
+ },
+ {
+ "81D667193D42BF19C456F4A1F7070C047D94C7EE8136FA315F938162FDDA20C1",
+ "2EFBA2B689C0F775097F98B569A1F20004F1A75F0C53473969DBE586ABCAE04D",
+ "447326913AA4565951D987F59B48870DD9285EEFCF64B429C2220E4F3E0D9DE2"
+ },
+ {
+ "891DF30BAEA2D24408A9C788D59DBAC7A6F34311813216311E18E9ED7122DB1A",
+ "F1629B62ECDF3CDAA3DA0EBB31EE37691AF4EB2B6F9CF04A9861935B2C167D02",
+ "C7BD348D5E6696CB8BA813B96EA5C42C5C3C3629D18FC9DAF1B50A0AE4843C5B"
+ },
+ {
+ "91C44D109D46C8E8656793680D43BE94",
+ "E68D8E49A19F155B7ED7253120B0D117",
+ "FAED8666F695C85283ECF51C96DB41CE"
+ }
+ },
+ {
+ {
+ "0CCFB49FE2B7E93A556E56B2C616885FBB0515F55A4210FE2F492A4775F078655CB21691CA6A54819C2D885954809D00",
+ "2FC6C785D683FC35304DD161A21FA1B256F9FBB2817F1F3BEBCE7C1E292EC6999641AA6953C0FAB6DFC2942CABD32DFB",
+ "31FAF4E3DA19D2372666AC635FFE361E33AD7865AEF616273D8F3B471F77A0998C6A41497168A65F621D912C54A4AF28"
+ },
+ {
+ "0B3842152A6365ED14AD952ABBBAF0EED2E8F36250DD25DDA301490FDE05219B",
+ "696BF21A887A04E194DCC18719E1BD623D8BD25A0CEF5EC2E21312ACE6C81F40",
+ "A2C8E61471EC80FE39AC0D8F720FEA8F2D23D04596A751C755E51CD357BCA5E0"
+ },
+ {
+ "5E0EA3AFBE191A16854C7960F087958F577EA4F80160F521A12D2211FAC25E16",
+ "F5475B4FD48F969123C9F7FB08C7E902CCA282F167BBAFF1A7C7EDDB7BCBAC76",
+ "380CB860EC6DEF4F9329F4BE826DE1FE61A71629DD978F00BEFB349ACBD0BAD8"
+ },
+ {
+ "BA1452E755E6A43E43B10DD2C1530093",
+ "07CA52926D4E8F2F6055E6E0251CB9E5",
+ "AB99E5FEE195B4433667AD3074A9322E"
+ }
+ },
+ {
+ {
+ "D2D46E577723B30E6B5FC96DC18B2C55E0EACCB07CE07C7F30FD113A987E2A2059AB7DF8985C1AE525EFAD9CE111893C",
+ "CC5B220688AC0231DBC03C8886C0D0109840B9E58FBB1A6B6C261ED9E7979E951818033A25778FF328786D1777790078",
+ "4B4A0B3D6D4E770BECC574BF66CD401942DC4D0DCD0EC65F99B2925B688BB217FCB5C946BE986C440C93279F4670CD43"
+ },
+ {
+ "29C76D62D3C4F7FECCBFD7A73B06E2ECA7AA3B2D4BE79EC945B0B88C813264D8",
+ "B898DCE11F3D6BB2182208E0BBBA7F404FE415D4D6D0772960E7CE3549B9899C",
+ "11E9552009836B51F241E972D680A9F397260163D9D5369BFC1B136FB4206966"
+ },
+ {
+ "539FC6EDAE21EDDC1CC4650367F527467916A6990E540146238AA9CD6B3B4ADE",
+ "2D9DE2BC47DAFCF7867134110C541EBCD72D67B1B23DEF6805DBFF4A4D90EF91",
+ "BF484690835FF61C4A7873A996EEB91F553978A40360E192273D3923E04DFE1E"
+ },
+ {
+ "4910EFFFBF571C98D51802F04A42213E",
+ "EDD1880FC4D41293BC74B98AF3D8A010",
+ "F8BCC258A6CD7FAA4EDF16A3CF5573C4"
+ }
+ },
+ {
+ {
+ "C2061BD0B4274B5CB4E408B492991F4195FDBFCDED1BC57442151B182BA6E8075AAF858F357C262E0034B9B5F839D823",
+ "6EEFEBCC9F8C607D21A158E23980EFA6EC234DC6EA668A446F467F4AE87521F18DC1800D87A5EBC63C444F810557B61D",
+ "00C952BA54614A1F11B0D59F3F469A859F62CCE0D35073B91B461302A7F37BD0B23401482DFCEE66ABD12C05615C9862"
+ },
+ {
+ "B36553D93EEF04AE247DBCBDDB8C039FFAC8AC1B0EF14C2E4BA653F089924451",
+ "90670C9DE58F95431591FA2BE8EA1B4B3F5BDBFC0B5199F94A41E4FC7B6B1645",
+ "A065415413D3A08E4B42A3F2681B8D122167A1E3F92D38C305761D9BF80131F1"
+ },
+ {
+ "12A758F161543F2842138B8C2453C3A05A90BE9F92CB3DD10C40AB9D1D746B49",
+ "DF1F4DDFFE1032C812FC6F35AB2B3A7B0E8D26DA49DEC8F5E08D108DB1283BEA",
+ "FDCB66159E1B5CF1BE9F7271EF2C35D5E9F7485E32D16C6AC865E64619DB8724"
+ },
+ {
+ "1FC224DCB64848B5E8F9FB91C542991F",
+ "1F8C5F65F9205098B47E26894B9154D9",
+ "19763CAC206EDFDEBEDAD9C274DEE1C1"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "69836472094875029486750948672066",
+ "48670943876904867104398574908554"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+ ByteString keyData128(testKeys128[i]);
+ ByteString keyData192(testKeys192[i]);
+ ByteString keyData256(testKeys256[i]);
+
+ AESKey aesKey128(128);
+ CPPUNIT_ASSERT(aesKey128.setKeyBits(keyData128));
+ AESKey aesKey192(192);
+ CPPUNIT_ASSERT(aesKey192.setKeyBits(keyData192));
+ AESKey aesKey256(256);
+ CPPUNIT_ASSERT(aesKey256.setKeyBits(keyData256));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+ // Test 128-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey128, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey128, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 192-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey192, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey192, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 256-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey256, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey256, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void AESTests::testECB()
+{
+ char testKeys128[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "89436760984679018453504364534464",
+ "49587346983643545706904580436731"
+ };
+
+ char testKeys192[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101213141516171819",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "096874395874290867409857496743857632098479834634",
+ "439867439058743095864395348375043296845094854983"
+ };
+
+ char testKeys256[][65] =
+ {
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20",
+ "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F",
+ "4394398576098257436095746985679043867498572406874967416846341641",
+ "4369006859867098670492857409386741095643756930847023587048579014"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "6CAEC72F5E101C66550215ACAB6B874CD26479922B98D9839D7DA729B557ABA00143DB63EE66B0CDFF9F69917680151E",
+ "E20E3123AC64FCA5536E0A2DC48DBEBC0E4E53BDA45FFC97C677951A891A6B7502BB292527E726FD51EB29894D6F0AAD",
+ "C7910B1634DB493998608875A4652B205750B3B761DA7718E120C23A575F7D821F788FE6D86C317549697FBF0C07FA43"
+ },
+ {
+ "8F48A65BF638FEDB7E6F59BAC8C110FE0E5E6370CBEFACFA0D7A5744030A481B",
+ "125E1D93DC2C43A6FAFC508DB6F9A4A933738D14C219340D5F4D7203DEDCA7E1",
+ "FACB8DEF1B476400DE9796D5058E90863A9A8C8BB2420B9A85BA3E8F87BB48F2"
+ },
+ {
+ "C810E96482F109C9A05D2B1BEBAC79660143DB63EE66B0CDFF9F69917680151E",
+ "2385391BB8F2DD97280B1FAEFACB6B5C02BB292527E726FD51EB29894D6F0AAD",
+ "47549520EADA1A5D931EACCC922F88BA1F788FE6D86C317549697FBF0C07FA43"
+ },
+ {
+ "A7D9EAE80224624188CAA7012140E946",
+ "6ECD5C71ECA4AB9C3B71E91721CA2043",
+ "2F77AA438E9259F268985668B00650E5"
+ }
+ },
+ {
+ {
+ "8947CE273536C8A4D1E878F38371B9A8D2B3B45496779386CBA32CA70001D6AA6CC00A66D2AD83FFD76E9A2BCAD89A01",
+ "B151340CFECADA3AE176637D0A78686E2063E1A602C85D03AE648BDF4FA57C36F7F1878D088644BD5FB43D3C0FE1C30C",
+ "C19AE024C8F6B8E3383F675DF463512E273AAD7D0B88F22D5225EF09D2E37118D45D7C5AA26BCA9D6B1D5DDBF68F9EF6"
+ },
+ {
+ "16C30BBAE7CDB2EE1E02275B79A064F6EE69FB37C8E039400435782F550CF86A",
+ "F6C869D28D2D167C50BEE8F605D33021CB9173567B8B4AB3EEC68F0298324B78",
+ "07DB563F7E31F1E670A02F97E8D120C7EE3FCEBBF2FDC2D37FC17D93ED1A778B"
+ },
+ {
+ "52902B599686234833C4D420A9BF17FF6CC00A66D2AD83FFD76E9A2BCAD89A01",
+ "B17FA9EA89D5578A844B3D82891330B1F7F1878D088644BD5FB43D3C0FE1C30C",
+ "74BC55BE85291E0D1FA4A4444051CF65D45D7C5AA26BCA9D6B1D5DDBF68F9EF6"
+ },
+ {
+ "3F00CAAC6FA432A7C1826CA4DA7C55D6",
+ "9C2DBF449FF2C4AC1CFD7C43D200D33A",
+ "E2183AB600A986806D86ADA4EE38E562"
+ }
+ },
+ {
+ {
+ "23741EF993CBA04E5C67B42A16CA4D100BA6DF745E6D90818500DEC1CFC9811DBD3ACBFC853ED5DE825266C3B1883EC4",
+ "F14D0EB7DFDB9B8960B0E47D7F4828E8756C38BA83655AAC466986ECB229A66FA390265A4BF5F50A8DFFAD253701E418",
+ "0AAE579A796C94AF4FFB9D7C71381CB5E68E15465F30D7085A72D0CCEC7030BBC9CB7B3859E1A550BCBF11B624022C56"
+ },
+ {
+ "AFCD6801459845C88548CC337BDD4D8B87E81D9D6AC945E14E3C4E0AC976A4B9",
+ "117129A4775FC84E703F2F2C54B1B55DC4A79241F6CB0A37A8D551D71983D944",
+ "1128250DA7C9A1BBE6A61AC01F28D4D9E3027C3625BD5514AE5DFE4B9132DAFA"
+ },
+ {
+ "B275BDAF14AE286643C533258343F822BD3ACBFC853ED5DE825266C3B1883EC4",
+ "93ACFCCFE2C4736B6492A673A59DACE2A390265A4BF5F50A8DFFAD253701E418",
+ "2C2165E6491662A855FD7A20CDFF23BDC9CB7B3859E1A550BCBF11B624022C56"
+ },
+ {
+ "30BBF52D760BAEA653FD03E5E84E583A",
+ "F5F55DF3FC4D9CF2A2829BACA774A51A",
+ "7EE196D148C11FA4998A90C6C7932395"
+ }
+ },
+ {
+ {
+ "44C2B3344B002BB7A6994E1C74CC7BA70CE55BF44FD96506B553F0EFD3FE02B28329D59D480B0C1714A0DC60EB9FA8CE",
+ "568C7627FD2519BE6031F052DE8F680860F7680460E92A524EA912174BE17B1337D593DEF15FB5BA64F03D1AAE276775",
+ "99E36C0097BCFE41945C064EFA476FF4AA6048F909BEDE32A649F1035A2FB83CD601D09C3FDB36BC61B8CDE5BDD73804"
+ },
+ {
+ "D748E8E93D29775BD8831E3BC1E1ABF75F484C7CC693521A66A5AB1637822E40",
+ "010103778E123E5140F8D0356DA831E1587DB7E416AE9FAD14C6E2F78DC83148",
+ "A8B8926E8FB762A1AB8CD9FA08507D77872C8EAAAFF3527572F49497B8B366C9"
+ },
+ {
+ "CFF3212C7E94C2DD65EC1CDC998D6C4B8329D59D480B0C1714A0DC60EB9FA8CE",
+ "324D16FEEC9DCA75A80F4B80175F8A7537D593DEF15FB5BA64F03D1AAE276775",
+ "850567F4F0200CFBF88F1A6D35CAF6D9D601D09C3FDB36BC61B8CDE5BDD73804"
+ },
+ {
+ "417F142D7609AE701B3D263FFECE4502",
+ "E0DC994D8DC01C4EB2ECD19AD120C3D1",
+ "FB26CC4E48B40EAB755FF65164EFB406"
+ }
+ },
+ {
+ {
+ "048AEE75741BC60D01B512A53FEE97238F294743E7A351FAF589DD9E040BB8AF0F59D8F60E9C700F10025B5E69828819",
+ "67FB10E52640B1E060F3D7868524721AC375DC76628B0D79C5F40ADC653FC001B50C33356548289D3E70EB7FBC0E2B56",
+ "31953FF249D7519D3C39FB21D70A41033286A320193CC938C5ACBBCA2B25340829799212E3CABACE0BFD4424427705AB"
+ },
+ {
+ "8D8D50FA4619F0E1B821DCA4ACBDFD46AE92D76A0B95A0331D61C4A7032D9705",
+ "10685E8F632AC41D92E3A0403BB20C79868BD6F94691226EC54D7220C45E7233",
+ "C5FF99FD1BC2BFDBEA62894B279DE6CBF51CCD00362A557DB9D9102DAF623A50"
+ },
+ {
+ "0330B8FF58E4E6E956B4F81F7A4770200F59D8F60E9C700F10025B5E69828819",
+ "C79BABE5B34B305B05E38013DC5568F7B50C33356548289D3E70EB7FBC0E2B56",
+ "98BEE460FF803288C898A900DD08CE2529799212E3CABACE0BFD4424427705AB"
+ },
+ {
+ "9A4FD3A26DD0D3A12F224E5E7A06EB76",
+ "B86FE6F088C3A6497F21BCB29DB703D1",
+ "313CC604B301DACA48CDB6F405AA7938"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "69836472094875029486750948672066",
+ "48670943876904867104398574908554"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+ ByteString keyData128(testKeys128[i]);
+ ByteString keyData192(testKeys192[i]);
+ ByteString keyData256(testKeys256[i]);
+
+ AESKey aesKey128(128);
+ CPPUNIT_ASSERT(aesKey128.setKeyBits(keyData128));
+ AESKey aesKey192(192);
+ CPPUNIT_ASSERT(aesKey192.setKeyBits(keyData192));
+ AESKey aesKey256(256);
+ CPPUNIT_ASSERT(aesKey256.setKeyBits(keyData256));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+ // Test 128-bit key
+
+ // Get the reference for the encrypted data
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey128, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey128, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 192-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey192, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey192, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 256-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey256, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey256, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void AESTests::testCTR()
+{
+ // Test vectors from RFC3686
+
+ char testKeys128[][33] =
+ {
+ "AE6852F8121067CC4BF7A5765577F39E",
+ "7E24067817FAE0D743D6CE1F32539163",
+ "7691BE035E5020A8AC6E618529F9A0DC"
+ };
+
+ char testKeys192[][49] =
+ {
+ "16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515",
+ "7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A",
+ "02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE"
+ };
+
+ char testKeys256[][65] =
+ {
+ "776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104",
+ "F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884",
+ "FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D"
+ };
+
+ char testData[][256] =
+ {
+ "53696E676C6520626C6F636B206D7367",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223"
+ };
+
+ char testResult[3][3][256] =
+ {
+ {
+ "E4095D4FB7A7B3792D6175A3261311B8",
+ "4B55384FE259C9C84E7935A003CBE928",
+ "145AD01DBF824EC7560863DC71E3E0C0"
+ },
+ {
+ "5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28",
+ "453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00",
+ "F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C"
+ },
+ {
+ "C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F",
+ "96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935",
+ "EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8"
+ }
+ };
+
+ char testCB[3][3][33] =
+ {
+ {
+ "00000030000000000000000000000001",
+ "0000004836733C147D6D93CB00000001",
+ "00000060DB5672C97AA8F0B200000001"
+ },
+ {
+ "006CB6DBC0543B59DA48D90B00000001",
+ "0096B03B020C6EADC2CB500D00000001",
+ "00FAAC24C1585EF15A43D87500000001"
+ },
+ {
+ "00E0017B27777F3F4A1786F000000001",
+ "0007BDFD5CBD60278DCC091200000001",
+ "001CC5B751A51D70A1C1114800000001"
+ }
+ };
+
+ for (int i = 0; i < 3; i++)
+ {
+ ByteString keyData128(testKeys128[i]);
+ ByteString keyData192(testKeys192[i]);
+ ByteString keyData256(testKeys256[i]);
+
+ AESKey aesKey128(128);
+ CPPUNIT_ASSERT(aesKey128.setKeyBits(keyData128));
+ AESKey aesKey192(192);
+ CPPUNIT_ASSERT(aesKey192.setKeyBits(keyData192));
+ AESKey aesKey256(256);
+ CPPUNIT_ASSERT(aesKey256.setKeyBits(keyData256));
+
+
+ ByteString plainText(testData[i]), shsmPlainText;
+ ByteString CB;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+ // Test 128-bit key
+ CB = ByteString(testCB[i][0]);
+ cipherText = ByteString(testResult[i][0]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey128, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey128, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 192-bit key
+ CB = ByteString(testCB[i][1]);
+ cipherText = ByteString(testResult[i][1]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey192, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey192, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 256-bit key
+ CB = ByteString(testCB[i][2]);
+ cipherText = ByteString(testResult[i][2]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey256, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey256, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+}
+
+#ifdef WITH_AES_GCM
+void AESTests::testGCM()
+{
+ // Test vectors from NIST via Botan
+
+ char test128[8][6][256] =
+ {
+ {
+ "00000000000000000000000000000000",
+ "000000000000000000000000",
+ "",
+ "",
+ "10",
+ "58E2FCCEFA7E3061367F1D57A4E7455A"
+ },
+ {
+ "00000000000000000000000000000000",
+ "000000000000000000000000",
+ "00000000000000000000000000000000",
+ "",
+ "10",
+ "0388DACE60B6A392F328C2B971B2FE78AB6E47D42CEC13BDF53A67B21257BDDF"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "CAFEBABEFACEDBADDECAF888",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B391AAFD255",
+ "",
+ "10",
+ "42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E091473F59854D5C2AF327CD64A62CF35ABD2BA6FAB4"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "CAFEBABEFACEDBADDECAF888",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "10",
+ "42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E0915BC94FBC3221A5DB94FAE95AE7121A47"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "CAFEBABEFACEDBAD",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "10",
+ "61353B4C2806934A777FF51FA22A4755699B2A714FCDC6F83766E5F97B6C742373806900E49F24B22B097544D4896B424989B5E1EBAC0F07C23F45983612D2E79E3B0785561BE14AACA2FCCB"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "9313225DF88406E555909C5AFF5269AA6A7A9538534F7DA1E4C303D2A318A728C3C0C95156809539FCF0E2429A6B525416AEDBF5A0DE6A57A637B39B",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "10",
+ "8CE24998625615B603A033ACA13FB894BE9112A5C3A211A8BA262A3CCA7E2CA701E4A9A4FBA43C90CCDCB281D48C7C6FD62875D2ACA417034C34AEE5619CC5AEFFFE0BFA462AF43C1699D050"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "CAFEBABEFACEDBAD",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "C",
+ "61353B4C2806934A777FF51FA22A4755699B2A714FCDC6F83766E5F97B6C742373806900E49F24B22B097544D4896B424989B5E1EBAC0F07C23F45983612D2E79E3B0785561BE14A"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "9313225DF88406E555909C5AFF5269AA6A7A9538534F7DA1E4C303D2A318A728C3C0C95156809539FCF0E2429A6B525416AEDBF5A0DE6A57A637B39B",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "C",
+ "8CE24998625615B603A033ACA13FB894BE9112A5C3A211A8BA262A3CCA7E2CA701E4A9A4FBA43C90CCDCB281D48C7C6FD62875D2ACA417034C34AEE5619CC5AEFFFE0BFA462AF43C"
+ }
+ };
+
+ char test192[8][6][256] =
+ {
+ {
+ "000000000000000000000000000000000000000000000000",
+ "000000000000000000000000",
+ "",
+ "",
+ "10",
+ "cd33b28ac773f74ba00ed1f312572435"
+ },
+ {
+ "000000000000000000000000000000000000000000000000",
+ "000000000000000000000000",
+ "00000000000000000000000000000000",
+ "",
+ "10",
+ "98e7247c07f0fe411c267e4384b0f6002ff58d80033927ab8ef4d4587514f0fb"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
+ "",
+ "10",
+ "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade2569924a7c8587336bfb118024db8674a14"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda27102519498e80f1478f37ba55bd6d27618c"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbad",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f765dcc57fcf623a24094fcca40d3533f8"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373bdcf566ff291c25bbb8568fc3d376a6d9"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "C",
+ "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda27102519498e80f1478f37ba55bd"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbad",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "C",
+ "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f765dcc57fcf623a24094fcca4"
+ }
+ };
+
+ char test256[8][6][256] =
+ {
+ {
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000",
+ "",
+ "",
+ "10",
+ "530f8afbc74536b9a963b4f1c4cb738b"
+ },
+ {
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000",
+ "00000000000000000000000000000000",
+ "",
+ "10",
+ "cea7403d4d606b6e074ec5d3baf39d18d0d1c8a799996bf0265b98b5d48ab919"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
+ "",
+ "10",
+ "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015adb094dac5d93471bdec1a502270e3cc6c"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f66276fc6ece0f4e1768cddf8853bb2d551b"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbad",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f3a337dbf46a792c45e454913fe2ea8f2",
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3fa44a8266ee1c8eb0c8b5d4cf5ae9f19a"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "C",
+ "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f66276fc6ece0f4e1768cddf8853"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbad",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "C",
+ "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f3a337dbf46a792c45e454913"
+ }
+ };
+
+ for (int i = 0; i < 8; i++)
+ {
+ ByteString keyData128(test128[i][0]);
+ ByteString keyData192(test192[i][0]);
+ ByteString keyData256(test256[i][0]);
+
+ AESKey aesKey128(128);
+ CPPUNIT_ASSERT(aesKey128.setKeyBits(keyData128));
+ AESKey aesKey192(192);
+ CPPUNIT_ASSERT(aesKey192.setKeyBits(keyData192));
+ AESKey aesKey256(256);
+ CPPUNIT_ASSERT(aesKey256.setKeyBits(keyData256));
+
+ ByteString IV;
+ ByteString plainText;
+ ByteString AAD;
+ size_t tagBits;
+ ByteString cipherText;
+
+ ByteString shsmPlainText;
+ ByteString shsmCipherText;
+ ByteString OB;
+
+ // Test 128-bit key
+ IV = ByteString(test128[i][1]);
+ plainText = ByteString(test128[i][2]);
+ AAD = ByteString(test128[i][3]);
+ tagBits = ByteString(test128[i][4]).long_val();
+ cipherText = ByteString(test128[i][5]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey128, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey128, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ CPPUNIT_ASSERT(OB.size() == 0);
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 192-bit key
+ IV = ByteString(test192[i][1]);
+ plainText = ByteString(test192[i][2]);
+ AAD = ByteString(test192[i][3]);
+ tagBits = ByteString(test192[i][4]).long_val();
+ cipherText = ByteString(test192[i][5]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey192, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey192, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ CPPUNIT_ASSERT(OB.size() == 0);
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 256-bit key
+ IV = ByteString(test256[i][1]);
+ plainText = ByteString(test256[i][2]);
+ AAD = ByteString(test256[i][3]);
+ tagBits = ByteString(test256[i][4]).long_val();
+ cipherText = ByteString(test256[i][5]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey256, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey256, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ CPPUNIT_ASSERT(OB.size() == 0);
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+}
+#endif
+
+void AESTests::testWrap(const char testKeK[][128], const char testKey[][128], const char testCt[][128], const int testCnt, SymWrap::Type mode)
+{
+ for (int i = 0; i < testCnt; i++)
+ {
+ ByteString kekData(testKeK[i]);
+ ByteString keyData(testKey[i]);
+
+ AESKey aesKeK(kekData.size() * 8);
+ CPPUNIT_ASSERT(aesKeK.setKeyBits(kekData));
+
+ ByteString wrapped;
+ ByteString expectedCt(testCt[i]);
+ CPPUNIT_ASSERT(aes->wrapKey(&aesKeK, mode, keyData, wrapped));
+ CPPUNIT_ASSERT(wrapped.size() == expectedCt.size());
+ CPPUNIT_ASSERT(wrapped == expectedCt);
+
+ ByteString unwrapped;
+ CPPUNIT_ASSERT(aes->unwrapKey(&aesKeK, mode, wrapped, unwrapped));
+ CPPUNIT_ASSERT(unwrapped.size() == keyData.size());
+ CPPUNIT_ASSERT(unwrapped == keyData);
+/*
+ #ifdef HAVE_AES_KEY_WRAP_PAD
+ keyData.resize(20);
+ ByteString padwrapped;
+ CPPUNIT_ASSERT(aes->wrapKey(&aesKeK, SymWrap::AES_KEYWRAP_PAD, keyData, padwrapped));
+ CPPUNIT_ASSERT(padwrapped.size() == 32);
+
+ ByteString padunwrapped;
+ CPPUNIT_ASSERT(aes->unwrapKey(&aesKeK, SymWrap::AES_KEYWRAP_PAD, padwrapped, padunwrapped));
+ CPPUNIT_ASSERT(padunwrapped == keyData);
+ #endif
+*/
+ }
+}
+
+// RFC 3394 tests
+void AESTests::testWrapWoPad()
+{
+ char testKeK[][128] = {
+ "000102030405060708090A0B0C0D0E0F", // section 4.1
+ "000102030405060708090A0B0C0D0E0F1011121314151617", // section 4.2
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", // section 4.3
+ "000102030405060708090A0B0C0D0E0F1011121314151617", // section 4.4
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", // section 4.5
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", // section 4.6
+ };
+ char testKey[][128] = {
+ "00112233445566778899AABBCCDDEEFF",
+ "00112233445566778899AABBCCDDEEFF",
+ "00112233445566778899AABBCCDDEEFF",
+ "00112233445566778899AABBCCDDEEFF0001020304050607",
+ "00112233445566778899AABBCCDDEEFF0001020304050607",
+ "00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F"
+ };
+ char testCt[][128] = {
+ "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5",
+ "96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D",
+ "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7",
+ "031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2",
+ "A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1",
+ "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21"
+ };
+
+ testWrap(testKeK, testKey, testCt, sizeof(testKeK) / 128, SymWrap::AES_KEYWRAP);
+}
+
+// RFC 5649 tests
+void AESTests::testWrapPad()
+{
+ char testKeK[][128] = {
+ "5840DF6E29B02AF1AB493B705BF16EA1AE8338F4DCC176A8", // section 6 example 1
+ "5840DF6E29B02AF1AB493B705BF16EA1AE8338F4DCC176A8", // section 6 example 2
+ };
+ char testKey[][128] = {
+ "C37B7E6492584340BED12207808941155068F738",
+ "466F7250617369"
+ };
+ char testCt[][128] = {
+ "138BDEAA9B8FA7FC61F97742E72248EE5AE6AE5360D1AE6A5F54F373FA543B6A",
+ "AFBEB0F07DFBF5419200F2CCB50BB24F"
+ };
+
+ testWrap(testKeK, testKey, testCt, sizeof(testKeK) / 128, SymWrap::AES_KEYWRAP_PAD);
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/AESTests.h b/SoftHSMv2/src/lib/crypto/test/AESTests.h
new file mode 100644
index 0000000..3a50b11
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/AESTests.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AESTests.h
+
+ Contains test cases to test the AES implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_AESTESTS_H
+#define _SOFTHSM_V2_AESTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "SymmetricAlgorithm.h"
+
+class AESTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(AESTests);
+ CPPUNIT_TEST(testBlockSize);
+ CPPUNIT_TEST(testCBC);
+ CPPUNIT_TEST(testECB);
+ CPPUNIT_TEST(testCTR);
+#ifdef WITH_AES_GCM
+ CPPUNIT_TEST(testGCM);
+#endif
+#ifdef HAVE_AES_KEY_WRAP
+ CPPUNIT_TEST(testWrapWoPad);
+#endif
+#ifdef HAVE_AES_KEY_WRAP_PAD
+ CPPUNIT_TEST(testWrapPad);
+#endif
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testBlockSize();
+ void testCBC();
+ void testECB();
+ void testCTR();
+#ifdef WITH_AES_GCM
+ void testGCM();
+#endif
+ void testWrapWoPad();
+ void testWrapPad();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // AES instance
+ SymmetricAlgorithm* aes;
+ void testWrap(const char testKeK[][128], const char testKey[][128], const char testCt[][128], const int testCnt, SymWrap::Type mode);
+};
+
+#endif // !_SOFTHSM_V2_AESTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/DESTests.cpp b/SoftHSMv2/src/lib/crypto/test/DESTests.cpp
new file mode 100644
index 0000000..bcb1c6b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DESTests.cpp
@@ -0,0 +1,1164 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DESTests.cpp
+
+ Contains test cases to test the DES implementation
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "DESTests.h"
+#include "CryptoFactory.h"
+#include "DESKey.h"
+#include <stdio.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DESTests);
+
+void DESTests::setUp()
+{
+ des = NULL;
+
+ des = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::DES);
+
+ // Check the return value
+ CPPUNIT_ASSERT(des != NULL);
+}
+
+void DESTests::tearDown()
+{
+ if (des != NULL)
+ {
+ CryptoFactory::i()->recycleSymmetricAlgorithm(des);
+ }
+
+ fflush(stdout);
+}
+
+void DESTests::testBlockSize()
+{
+ CPPUNIT_ASSERT(des->getBlockSize() == 8);
+}
+
+void DESTests::testCBC()
+{
+#ifndef WITH_FIPS
+ char testKeys56[][17] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4698436794236871",
+ "0940278947239572"
+ };
+
+ char testKeys112[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "64398647034486943598534703463870",
+ "87406984068406984607412103517413"
+ };
+#endif
+
+ char testKeys168[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "643906874509874309687459084769847562436043696747",
+ "430135460496813044639085714376487549490586439575"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "ACC8B1BE444EEA9E016A46EF600E9B3FB2C87DE8CE9BE5394917AABB0A04639A3BFF1E250FE971D7",
+ "ACC8B1BE444EEA9E016A46EF600E9B3FB2C87DE8CE9BE5394917AABB0A04639A3BFF1E250FE971D7",
+ "ACC8B1BE444EEA9E016A46EF600E9B3FB2C87DE8CE9BE5394917AABB0A04639A3BFF1E250FE971D7"
+ },
+ {
+ "F9A1913AA27A05379506BE00D5F7398F67722076A3439E759BA729A58E8FEE64",
+ "F9A1913AA27A05379506BE00D5F7398F67722076A3439E759BA729A58E8FEE64",
+ "F9A1913AA27A05379506BE00D5F7398F67722076A3439E759BA729A58E8FEE64"
+ },
+ {
+ "36FD5581BB31F3E27910895DC2F2599CD0F8B8F002220588",
+ "36FD5581BB31F3E27910895DC2F2599CD0F8B8F002220588",
+ "36FD5581BB31F3E27910895DC2F2599CD0F8B8F002220588"
+ },
+ {
+ "B81DA29972385E55CB453A17B6D88D22",
+ "B81DA29972385E55CB453A17B6D88D22",
+ "B81DA29972385E55CB453A17B6D88D22"
+ }
+ },
+ {
+ {
+ "EE16FFE3CC4D4589766FA0957FB728A75D44A00D9BEBE2D43C4D4F3A5AFDB49730CFD4DF46D3AEF6",
+ "A070EE9DED89EE198E0E9B3CEB4879BB0244AB7FCD3450ED044BB5EE0AC8F7797383FDB8AAEF77B8",
+ "E7C594590C9CA00B376B702CE3B92C3F699B3EEEB2CEA08FA551350C837BF031FCAF4E1E97450327"
+ },
+ {
+ "D4142C47C700069F3E71EA6B1EF301B9B97261543ED75B32242C05A253B077B8",
+ "102BBE7D93CD0EF66280D3FA1F2A3976FB9C4D1B155D19E4985ADB86015DDE8C",
+ "600C3A75AC6EB4C4609BA6B7ED273ED56E59CD49FC911C33DD8DFCA384BAA462"
+ },
+ {
+ "47452120CD84CC32FC72F3B8600E5C43EEE192A29BC6BCB7",
+ "ADCF4292A32E51A7843CC8590E6934083A2CC847082FF2B4",
+ "D0FA596AC00BDA870999FD3FA2494C3C8B40B261EB3066F6"
+ },
+ {
+ "6BD20CDBE6E6ECAD6ED829FB43E92751",
+ "AE4379E371E295F63423F861B59111F0",
+ "2757FC58EDEEB8499EA9B49AB2729BAD"
+ }
+ },
+ {
+ {
+ "298621D5237F6230067DE7871DDBA6991E85CA14AD661D21357240923604D23A6A4119277B75B331",
+ "2C9F4FC0ACE7C8A4847472A0D5DDD42F36D3B2C46144B5A0ECDBB59806472E6257952DFD4DB9EBE5",
+ "679A832C630207E76BC1FF8371C61CA2518E37FE97EDED1B171E3E11807250145736949368AC822B"
+ },
+ {
+ "80FFD37B545675BB8C7CD317A73AB48CC0A39D3D9C11474EC3FD1220A066C034",
+ "F9228036718792EE86A85626AB1BC05E17F9CE21FF5D1723D0442CE852F004C3",
+ "D5F5F1EA7D8C2038FEDCBEDF157A5D2469A941FEC696D74DB8359CA5AECDD4CE"
+ },
+ {
+ "1ABB1CC10F589D993030A978B1B7F44AD52FFFEBF23638CA",
+ "D2423F54FA4978C95E4B13EF4DD6AA82DFD772F0FDAF5AD1",
+ "8128EC49D71F5711E5304E7C4423C63AD0EFC45453B66583"
+ },
+ {
+ "B9EE976AB97396047510C1DEA5C86A4B",
+ "46BA1930042146B31BD8FAF3AE6F3414",
+ "46EF3BCCA73E33C03D81BFE0DFFA7ABD"
+ }
+ },
+ {
+ {
+ "30D1B2556D516F20C2FD117FE0355845FBB0B11ABE5922A7EAA19C3A48E30207218321B3F0F30A6D",
+ "CBFA560297901DD691CDFDF98675BD7FF3A64FDCC0EF02F29C81105D3ECAC4E2803E2279F4476B35",
+ "4A30EC10433BE3695DC2B064E6240419C7BF81F1EE7640D5E2FFFA106666A2CEBF18DB954A992B5E"
+ },
+ {
+ "61FFB2E5A73170603E48F9823E6DF7105C9A909CC2F5CEDBEA7E60C076355B37",
+ "8408BD722B12031D17A1645AA59B05E2A50F7002B19877D6EB1C9BB7107C523F",
+ "97EF5791017B10CF07FB8144C19633522CBBE55DC63EF608F8734EE6484C0B0E"
+ },
+ {
+ "7205DC463B3D5EC858C8E7A13844A1A8FF21C0D615CA56AF",
+ "D5D08C1DC728A47CD55A2ACBB811294962022E745F4BCDF4",
+ "7761189D73039A3F06BDDF00B308D7A43BE7BEA1CE9D042E"
+ },
+ {
+ "1702428661BA4CFE686CFDEDFFAA6A27",
+ "9218A89B0A7AEC7E6E2AF1CA493B2829",
+ "6EEB9F7DDF66CED3DB74F7E8DE0CB2CD"
+ }
+ },
+ {
+ {
+ "4FD3A4C759827F6E188E542B83A858026C17FD1DEF21477A964D122B62EE55FA9DB3CCF05A768C83",
+ "F2C8B52652970805EE60ECECC8369C98443463F1C3A5A6357DFDFEE6B7F1EF0CF05523B5469E4555",
+ "21FCBDC92C07F112D19742F5100F2A995E27CB282D73DF5CFEC802C629A279BD4E498C98D170003E"
+ },
+ {
+ "3FD4C32A44DC0A9605A5A793C57E94826E80FC9E8E9620BBC2E02FE41A62A2D3",
+ "4FC88F1E88C3B5A76CF6BE5FA8205BA6F7FA201F7C40E8F0F9CA156E140A4EC5",
+ "CCE31260C967F4B9BB3D2D31F82320715E434C1313D911C58CE7E42AA78DA831"
+ },
+ {
+ "714766BE5CB60DA99DC0BD4E7E655ADE7F26E45F372EF1BF",
+ "00064542E2B4821B4E9173DA6FD1ABAE45C5E5CF26DB506D",
+ "4D88D531C20E63A39372F275329BDBEBE15E7D2C32F2A98F"
+ },
+ {
+ "4933917C9B56124914D2B76DE221BA13",
+ "7F2D1CA9D942630FE1E954E4176E84A5",
+ "9A46902F3997F0EB121981DAEC6D89C4"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4693867334098764",
+ "6209876098547207"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+#ifndef WITH_FIPS
+ ByteString keyData56(testKeys56[i]);
+ CPPUNIT_ASSERT(keyData56.size() == 8);
+ ByteString keyData112(testKeys112[i]);
+ CPPUNIT_ASSERT(keyData112.size() == 16);
+#endif
+ ByteString keyData168(testKeys168[i]);
+ CPPUNIT_ASSERT(keyData168.size() == 24);
+
+#ifndef WITH_FIPS
+ DESKey desKey56(56);
+ CPPUNIT_ASSERT(desKey56.setKeyBits(keyData56));
+ DESKey desKey112(112);
+ CPPUNIT_ASSERT(desKey112.setKeyBits(keyData112));
+#endif
+ DESKey desKey168(168);
+ CPPUNIT_ASSERT(desKey168.setKeyBits(keyData168));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+#ifndef WITH_FIPS
+ // Test 56-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey56, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey56, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 112-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey112, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey112, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+#endif
+
+ // Test 168-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey168, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey168, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void DESTests::testECB()
+{
+#ifndef WITH_FIPS
+ char testKeys56[][17] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4698436794236871",
+ "0940278947239572"
+ };
+
+ char testKeys112[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "64398647034486943598534703463870",
+ "87406984068406984607412103517413"
+ };
+#endif
+
+ char testKeys168[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "643906874509874309687459084769847562436043696747",
+ "430135460496813044639085714376487549490586439575"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "ACC8B1BE444EEA9E44404B8595B7667982F1BDF99F419F083249964334F2B15F7E422822773666C0",
+ "ACC8B1BE444EEA9E44404B8595B7667982F1BDF99F419F083249964334F2B15F7E422822773666C0",
+ "ACC8B1BE444EEA9E44404B8595B7667982F1BDF99F419F083249964334F2B15F7E422822773666C0"
+ },
+ {
+ "F9A1913AA27A0537CA0BB1A6417C4037978BC92CEFCD10BB7E422822773666C0",
+ "F9A1913AA27A0537CA0BB1A6417C4037978BC92CEFCD10BB7E422822773666C0",
+ "F9A1913AA27A0537CA0BB1A6417C4037978BC92CEFCD10BB7E422822773666C0"
+ },
+ {
+ "36FD5581BB31F3E2ADA81678B64A0F3C7E422822773666C0",
+ "36FD5581BB31F3E2ADA81678B64A0F3C7E422822773666C0",
+ "36FD5581BB31F3E2ADA81678B64A0F3C7E422822773666C0"
+ },
+ {
+ "B81DA29972385E55EA1F3677CDC02D27",
+ "B81DA29972385E55EA1F3677CDC02D27",
+ "B81DA29972385E55EA1F3677CDC02D27"
+ }
+ },
+ {
+ {
+ "278B2CA6259C30E180CCB62E69F0841F235507E2FB3404FC2BC223E37E32B3A78207EA5D3E19A5FD",
+ "417579E3ABEF6F0D620B4FF88E2220457466420803140BFEFBA062A2A41D7C15061019377C6BFD8A",
+ "A676D0404F0F105B2073B9DD19C8C434428098BFC5AF1292FE12477340395F118F45B5BE23F16C4E"
+ },
+ {
+ "7D004390E5638E54077E2551B01BD52BFA1B98403ECE1AEF8207EA5D3E19A5FD",
+ "391B84593FEA836450318A6E943F1C3A4A6BD74E5001EB7A061019377C6BFD8A",
+ "DEAF58111ECCCB449F0C2564B52E360E4AACC8672ABBDF1A8F45B5BE23F16C4E"
+ },
+ {
+ "A6947F9EF4159BAE636A70B904059BC38207EA5D3E19A5FD",
+ "14ADFE212E27BF7F409395B45577F2C8061019377C6BFD8A",
+ "FF87BF761FC159F4442B3B4593233BC48F45B5BE23F16C4E"
+ },
+ {
+ "3A1777DAAAC85389EE0B499A90AE1739",
+ "376E61DF2EAFE5B523964A03885AD085",
+ "E4D81EE64FE8FB187EB7B5E80E075C73"
+ }
+ },
+ {
+ {
+ "F105809DF621715F4D3492E1EEC4A7DE0775A0632ECC13429DF0DC695A60882FA47F93E855A1445B",
+ "77C85215179312315997B4D0E997DB413176C80A8ED9F5EB9B726200224CE97C20A8A19F543BCCBD",
+ "AF1477E32B5BB1CA46D26B6020B3B48DB0A90A97B1BA60F032ADA648296EC92DEE924AA617423FD1"
+ },
+ {
+ "0FB3C3D9D93E0025F87909CD351D0116C0F684A204015E2CA47F93E855A1445B",
+ "67A66DB3209C406D2FE31AF6C36D24C7B32D0F8F1EAFA90020A8A19F543BCCBD",
+ "F85B1F07D788C59CD3DE6D562A175725DF596847ADEA8764EE924AA617423FD1"
+ },
+ {
+ "243A34CD70CE3819B9510980B6EFF3EAA47F93E855A1445B",
+ "997E145467B88D9D4C923797F539AC1620A8A19F543BCCBD",
+ "836788D7AD1F879B405438775FFD6D76EE924AA617423FD1"
+ },
+ {
+ "70856D6B67EE353F27EBB96462DACE63",
+ "D02F2A92C175A58001D89C4AEC476384",
+ "4ED379A40187826CAA90D2D6A05D5A9B"
+ }
+ },
+ {
+ {
+ "C79F67ABCE6F741CF6D5B7B4870397779AEB89F48805DD1A28305E804A4A2B91114E1CF0C7FA91DA",
+ "42956EA3B9415E8FE75B667A7C6B1ADF64D08E53C38DE733A776A97C7A8FC27E32945078552FA3E2",
+ "3685365AD0F07609E13CCDE69CEDC8CCA0C37262A87B734286B9119643AC3BABE435BDA25919BE86"
+ },
+ {
+ "09B882774309CC2B117586F5FA8BF7E4A5DA2A65E137665B114E1CF0C7FA91DA",
+ "0E52A9ABE753758D3C4F6326A8F689282D1DAB8AF6FC8CFF32945078552FA3E2",
+ "8DB6B9D50B5B8CE7DA56546CFF36C16BA3159E0EB7BD649AE435BDA25919BE86"
+ },
+ {
+ "025F9704F6ACD844BCFC6EBA809CD871114E1CF0C7FA91DA",
+ "1692C6A1DF9192C6D4125991EA9A9CBE32945078552FA3E2",
+ "6B848E67225EDDCCD7E8EC89ACDAA0AFE435BDA25919BE86"
+ },
+ {
+ "9D01CD89916AEE48AFE528A376E07AE9",
+ "6FA6A689405048060D65E1B1240B76B7",
+ "7EADEB7073D2EA995C5ED613C978817F"
+ }
+ },
+ {
+ {
+ "A98D0E8E72C589D80D240F192CF65C30FF3A1AB9D8CE54B09AA249C72E395AC3B40F19A649C1B237",
+ "33AC43C7A936665859431D18C089EE45F1356C34F5DF462D81BBFA42380A7E4F6732A473091A3673",
+ "FD4F2F77CCE20147CD0932B2E2D8D5978523F6A03D59E31E1F678A5DA4C350132E94F199555C371E"
+ },
+ {
+ "39453F3BF3C0CAE54279D96F4592359A5AEE6DD04D5F6162B40F19A649C1B237",
+ "E2AFCEEFF2317C520D890D7F2CB91ACD99D5DCAEC9C409016732A473091A3673",
+ "CB19BF88B2DEDDE981E048379A47BDF77ED5F815034CB07A2E94F199555C371E"
+ },
+ {
+ "9D466BACFA69266F7CC26D2C8B8CD203B40F19A649C1B237",
+ "265FDBCCF5F2325B3C8770ABEEECA4166732A473091A3673",
+ "C61E9B86A8A663AE1566CFFCF2046D6B2E94F199555C371E"
+ },
+ {
+ "380091B24160152B63EF067F6C189385",
+ "548EB237B455CBA0100A5C52A6F28C2B",
+ "066C3B0C5E6AF1E9BDD3DDAE5040F809"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4693867334098764",
+ "6209876098547207"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+#ifndef WITH_FIPS
+ ByteString keyData56(testKeys56[i]);
+ CPPUNIT_ASSERT(keyData56.size() == 8);
+ ByteString keyData112(testKeys112[i]);
+ CPPUNIT_ASSERT(keyData112.size() == 16);
+#endif
+ ByteString keyData168(testKeys168[i]);
+ CPPUNIT_ASSERT(keyData168.size() == 24);
+
+#ifndef WITH_FIPS
+ DESKey desKey56(56);
+ CPPUNIT_ASSERT(desKey56.setKeyBits(keyData56));
+ DESKey desKey112(112);
+ CPPUNIT_ASSERT(desKey112.setKeyBits(keyData112));
+#endif
+ DESKey desKey168(168);
+ CPPUNIT_ASSERT(desKey168.setKeyBits(keyData168));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+#ifndef WITH_FIPS
+ // Test 56-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey56, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey56, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 112-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey112, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey112, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+#endif
+
+ // Test 168-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey168, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey168, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void DESTests::testOFB()
+{
+#ifndef WITH_FIPS
+ char testKeys56[][17] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4698436794236871",
+ "0940278947239572"
+ };
+
+ char testKeys112[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "64398647034486943598534703463870",
+ "87406984068406984607412103517413"
+ };
+#endif
+
+ char testKeys168[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "643906874509874309687459084769847562436043696747",
+ "430135460496813044639085714376487549490586439575"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "C59E2ADDC8D9529368469843865740390AE5DDB1B5B816204395813968496846",
+ "C59E2ADDC8D9529368469843865740390AE5DDB1B5B816204395813968496846",
+ "C59E2ADDC8D9529368469843865740390AE5DDB1B5B816204395813968496846"
+ },
+ {
+ "D83E5E8D823844AE48567490687546090EE32BBFE7E3542F",
+ "D83E5E8D823844AE48567490687546090EE32BBFE7E3542F",
+ "D83E5E8D823844AE48567490687546090EE32BBFE7E3542F"
+ },
+ {
+ "E89FCA8099D6B1FF6795867965624526",
+ "E89FCA8099D6B1FF6795867965624526",
+ "E89FCA8099D6B1FF6795867965624526"
+ },
+ {
+ "CA253BAC45D205E236",
+ "CA253BAC45D205E236",
+ "CA253BAC45D205E236"
+ }
+ },
+ {
+ {
+ "3E9FB188FC11138D05109EA396CA48E1681DF27A857C3C4A9E92D3DC85A5F313",
+ "3440BEFCF35DC87716D8440F71BAF9ACD0441E10B9E5B525F0584499620086E2",
+ "DDB35281888DF064195C42D45E4E2571AD62113A228B5107D1AC849861C199C0"
+ },
+ {
+ "233FC5D8B6F005B02500727078E84ED16C1B0474D7277E45",
+ "29E0CAACB9BCDE4A36C8A8DC9F98FF9CD442E81EEBBEF72A",
+ "C01326D1C26CE659394CAE07B06C2341A964E73470D01308"
+ },
+ {
+ "139E51D5AD1EF0E10AC3809975FF4DFE",
+ "19415EA1A2522B1B190B5A35928FFCB3",
+ "F0B2B2DCD9821308168F5CEEBD7B206E"
+ },
+ {
+ "3124A0F9711A44FC5B",
+ "3BFBAF8D7E569F0648",
+ "D20843F00586A71547"
+ }
+ },
+ {
+ {
+ "E376288A10BD52CB7162ADA9A732D24B574B1E7CB4FF5C791FFEA2E481AD3049",
+ "FD82CFAE85B8581FFCF489F467D94B1B4FAAAEDDE4EC531ABD30D7EA235896AA",
+ "24D9411BA456571900244AEA3EA7159BAA96522B6F891606A8D9A559FE218A9B"
+ },
+ {
+ "FED65CDA5A5C44F65172417A4910D47B534DE872E6A41E76",
+ "E022BBFECF594E22DCE4652789FB4D2B4BAC58D3B6B71115",
+ "3979354BEEB741242034A639D08513ABAE90A4253DD25409"
+ },
+ {
+ "CE77C8D741B2B1A77EB1B3934407D754",
+ "D0832FF3D4B7BB73F32797CE84EC4E04",
+ "09D8A146F559B4750FF754D0DD921084"
+ },
+ {
+ "ECCD39FB9DB605BA2F",
+ "F239DEDF08B30F6EA2",
+ "2B62506A295D00685E"
+ }
+ },
+ {
+ {
+ "740A4786C73A7C6B52DAF270161895E13B4437C56B9837827C2FE237532F4C19",
+ "581B63C58404AEBECFDFD51D74A79836C11514685B47F3B02A2419AF0AA8C625",
+ "D5FCB196868673D136D480E0B6EFC33C589131D87A4AC004A6E0DE8ADC8DE611"
+ },
+ {
+ "69AA33D68DDB6A5672CA1EA3F83A93D13F42C1CB39C3758D",
+ "45BB1795CEE5B883EFCF39CE9A859E06C513E266091CB1BF",
+ "C85CC5C6CC6765EC16C46C3358CDC50C5C97C7D62811820B"
+ },
+ {
+ "590BA7DB96359F075D09EC4AF52D90FE",
+ "751A8398D50B4DD2C00CCB2797929D29",
+ "F8FD51CBD78990BD39079EDA55DAC623"
+ },
+ {
+ "7BB156F74A312B1A0C",
+ "57A072B4090FF9CF91",
+ "DA47A0E70B8D24A068"
+ }
+ },
+ {
+ {
+ "0855A84EAD2176C3F10B9DCFC8D1A379AF616FC5C5CD4E6D434353C52832F9F6",
+ "A8420E97462B0215AAC1DB0835D4064C6A8B123327FC396C9520BEA70B59B412",
+ "3461DEDF1B4893E16706900E1DDBE351E90C1300B9B01E8A518A01AD56E9AC8C"
+ },
+ {
+ "15F5DC1EE7C060FED11B711C26F3A549AB6799CB97960C62",
+ "B5E27AC70CCA14288AD137DBDBF6007C6E8DE43D75A77B63",
+ "29C1AA8F51A985DC47167CDDF3F9E561ED0AE50EEBEB5C85"
+ },
+ {
+ "25544813FC2E95AFFED883F52BE4A666",
+ "8543EECA1724E179A512C532D6E10353",
+ "19603E824A47708D68D58E34FEEEE64E"
+ },
+ {
+ "07EEB93F202A21B2AF",
+ "A7F91FE6CB205564F4",
+ "3BDACFAE9643C49039"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4693867334098764",
+ "6209876098547207"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+#ifndef WITH_FIPS
+ ByteString keyData56(testKeys56[i]);
+ CPPUNIT_ASSERT(keyData56.size() == 8);
+ ByteString keyData112(testKeys112[i]);
+ CPPUNIT_ASSERT(keyData112.size() == 16);
+#endif
+ ByteString keyData168(testKeys168[i]);
+ CPPUNIT_ASSERT(keyData168.size() == 24);
+
+#ifndef WITH_FIPS
+ DESKey desKey56(56);
+ CPPUNIT_ASSERT(desKey56.setKeyBits(keyData56));
+ DESKey desKey112(112);
+ CPPUNIT_ASSERT(desKey112.setKeyBits(keyData112));
+#endif
+ DESKey desKey168(168);
+ CPPUNIT_ASSERT(desKey168.setKeyBits(keyData168));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+#ifndef WITH_FIPS
+ // Test 56-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey56, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey56, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 112-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey112, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey112, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+#endif
+
+ // Test 168-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey168, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey168, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void DESTests::testCFB()
+{
+#ifndef WITH_FIPS
+ char testKeys56[][17] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4698436794236871",
+ "0940278947239572"
+ };
+
+ char testKeys112[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "64398647034486943598534703463870",
+ "87406984068406984607412103517413"
+ };
+#endif
+
+ char testKeys168[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "643906874509874309687459084769847562436043696747",
+ "430135460496813044639085714376487549490586439575"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "C59E2ADDC8D95293F8ED346ADAF018111F0B6726349664FF9B02C46C2EC5B96F",
+ "C59E2ADDC8D95293F8ED346ADAF018111F0B6726349664FF9B02C46C2EC5B96F",
+ "C59E2ADDC8D95293F8ED346ADAF018111F0B6726349664FF9B02C46C2EC5B96F"
+ },
+ {
+ "D83E5E8D823844AE748E369586FA76A2BFD1E668EC78D67B",
+ "D83E5E8D823844AE748E369586FA76A2BFD1E668EC78D67B",
+ "D83E5E8D823844AE748E369586FA76A2BFD1E668EC78D67B"
+ },
+ {
+ "E89FCA8099D6B1FFB3A24C435B847A73",
+ "E89FCA8099D6B1FFB3A24C435B847A73",
+ "E89FCA8099D6B1FFB3A24C435B847A73"
+ },
+ {
+ "CA253BAC45D205E270",
+ "CA253BAC45D205E270",
+ "CA253BAC45D205E270"
+ }
+ },
+ {
+ {
+ "3E9FB188FC11138D49C438ABB98A3846671A4DB257AA62C7929CD55A43E46D88",
+ "3440BEFCF35DC8773DD631A9C8CCF222009D45E301BBF6432A78E99416CE87D8",
+ "DDB35281888DF06446772085E3DE849298B4BE0089979260DDC59FACB17AD0BE"
+ },
+ {
+ "233FC5D8B6F005B0966FB313EA0DDFBECF19CBC937445A56",
+ "29E0CAACB9BCDE4AB219A19AA77E2C9A407C98A18BD56FDF",
+ "C01326D1C26CE6592FA4E9909D93A85BE005431046661C73"
+ },
+ {
+ "139E51D5AD1EF0E1E74DD9919AE65DB6",
+ "19415EA1A2522B1B5972F5DCBEEF4E01",
+ "F0B2B2DCD9821308815ADB01F0A16B76"
+ },
+ {
+ "3124A0F9711A44FC92",
+ "3BFBAF8D7E569F06CF",
+ "D20843F00586A715DB"
+ }
+ },
+ {
+ {
+ "E376288A10BD52CB06B42B4582A425907D2DF490EC14B478507BCDE58CE95B02",
+ "FD82CFAE85B8581F1409EB62D06A98E05C401607619DE1235822E2DEB74737E1",
+ "24D9411BA4565719BE9FF1A4D91F23B3BF8980A706747077583C8EB84AF63745"
+ },
+ {
+ "FED65CDA5A5C44F619325429C78F464D271807342B10F899",
+ "E022BBFECF594E22ABC22FA25024B6FD8F61337CBD1F023D",
+ "3979354BEEB741241F0D219B5521A488F870C849275FF8B9"
+ },
+ {
+ "CE77C8D741B2B1A7E488B94EB32C96FD",
+ "D0832FF3D4B7BB73AEC7646A3686ABCF",
+ "09D8A146F559B475A6258D03BC6F8BD3"
+ },
+ {
+ "ECCD39FB9DB605BAB2",
+ "F239DEDF08B30F6EE4",
+ "2B62506A295D00687E"
+ }
+ },
+ {
+ {
+ "740A4786C73A7C6B435071A654DA8FCC75BA3299969E327A2ABC7024378CF3AA",
+ "581B63C58404AEBE49FA5FA4032918813075279E836DFE9BAEDF37D9B21ABEE1",
+ "D5FCB196868673D1FA9C8A67E6A2449354B292E1A76BA11C416A394116857B29"
+ },
+ {
+ "69AA33D68DDB6A561FB6D6218FAC0E812514782FC6059E46",
+ "45BB1795CEE5B883232EBCCB672FC9C4803C6B827825FE94",
+ "C85CC5C6CC6765EC466B8F8AC8DFC91CB916F617873AF187"
+ },
+ {
+ "590BA7DB96359F07DB2F2CE68748425C",
+ "751A8398D50B4DD24E4681B6D0E880FC",
+ "F8FD51CBD78990BD5D088ECA798DA0E6"
+ },
+ {
+ "7BB156F74A312B1A8C",
+ "57A072B4090FF9CF1B",
+ "DA47A0E70B8D24A043"
+ }
+ },
+ {
+ {
+ "0855A84EAD2176C3D2C3DE4FB868CA2C1B0DF550E187E29808C45594C070FBF4",
+ "A8420E97462B02158D2CABD1574D072F8D83123CED9BA7CEDD7C2799E168F32D",
+ "3461DEDF1B4893E182BE36017DEBC6669B15269DFA4435A31EB1A0CE6A845176"
+ },
+ {
+ "15F5DC1EE7C060FEDC9B1B43A20588E7A073A300BEFC4CAD",
+ "B5E27AC70CCA142857CB807226DC1EA9B31BE81C0FDCD3FB",
+ "29C1AA8F51A985DC7E530E6EB7AEAC246F2ED097D09851CC"
+ },
+ {
+ "25544813FC2E95AF817E0897D4E22ECD",
+ "8543EECA1724E179543979F02103C150",
+ "19603E824A47708D80E29D3A61BAE5EA"
+ },
+ {
+ "07EEB93F202A21B250",
+ "A7F91FE6CB205564F2",
+ "3BDACFAE9643C49027"
+ }
+ }
+ };
+ char testIV[][33] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4693867334098764",
+ "6209876098547207"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+#ifndef WITH_FIPS
+ ByteString keyData56(testKeys56[i]);
+ CPPUNIT_ASSERT(keyData56.size() == 8);
+ ByteString keyData112(testKeys112[i]);
+ CPPUNIT_ASSERT(keyData112.size() == 16);
+#endif
+ ByteString keyData168(testKeys168[i]);
+ CPPUNIT_ASSERT(keyData168.size() == 24);
+
+#ifndef WITH_FIPS
+ DESKey desKey56(56);
+ CPPUNIT_ASSERT(desKey56.setKeyBits(keyData56));
+ DESKey desKey112(112);
+ CPPUNIT_ASSERT(desKey112.setKeyBits(keyData112));
+#endif
+ DESKey desKey168(168);
+ CPPUNIT_ASSERT(desKey168.setKeyBits(keyData168));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+#ifndef WITH_FIPS
+ // Test 56-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey56, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey56, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 112-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey112, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey112, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+#endif
+
+ // Test 168-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey168, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey168, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/DESTests.h b/SoftHSMv2/src/lib/crypto/test/DESTests.h
new file mode 100644
index 0000000..0834462
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DESTests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DESTests.h
+
+ Contains test cases to test the DES implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DESTESTS_H
+#define _SOFTHSM_V2_DESTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "SymmetricAlgorithm.h"
+
+class DESTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(DESTests);
+ CPPUNIT_TEST(testBlockSize);
+ CPPUNIT_TEST(testCBC);
+ CPPUNIT_TEST(testECB);
+ CPPUNIT_TEST(testOFB);
+ CPPUNIT_TEST(testCFB);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testBlockSize();
+ void testCBC();
+ void testECB();
+ void testOFB();
+ void testCFB();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // DES instance
+ SymmetricAlgorithm* des;
+};
+
+#endif // !_SOFTHSM_V2_DESTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/DHTests.cpp b/SoftHSMv2/src/lib/crypto/test/DHTests.cpp
new file mode 100644
index 0000000..354cdac
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DHTests.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHTests.cpp
+
+ Contains test cases to test the DH class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "DHTests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#include "DHParameters.h"
+#include "DHPublicKey.h"
+#include "DHPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DHTests);
+
+void DHTests::setUp()
+{
+ dh = NULL;
+
+ dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
+
+ // Check the DH object
+ CPPUNIT_ASSERT(dh != NULL);
+}
+
+void DHTests::tearDown()
+{
+ if (dh != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+ }
+
+ fflush(stdout);
+}
+
+void DHTests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ // Generate parameters
+ DHParameters* p;
+ AsymmetricParameters** ap = (AsymmetricParameters**) &p;
+
+ CPPUNIT_ASSERT(dh->generateParameters(ap, (void*) *k));
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kp, p));
+
+ DHPublicKey* pub = (DHPublicKey*) kp->getPublicKey();
+ DHPrivateKey* priv = (DHPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getBitLength() == *k);
+ CPPUNIT_ASSERT(priv->getBitLength() == *k);
+
+ dh->recycleKeyPair(kp);
+
+ // Generate key-pair with a fixed private value length
+ p->setXBitLength(128);
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kp, p));
+
+ priv = (DHPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(priv->getX().bits() == 128);
+
+ dh->recycleParameters(p);
+ dh->recycleKeyPair(kp);
+ }
+}
+
+void DHTests::testSerialisation()
+{
+ // Generate 1024-bit parameters for testing
+ DHParameters* p;
+ AsymmetricParameters** ap = (AsymmetricParameters**) &p;
+
+ CPPUNIT_ASSERT(dh->generateParameters(ap, (void*) 1024));
+
+ // Set a fixed private value length
+ p->setXBitLength(128);
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dP;
+
+ CPPUNIT_ASSERT(dh->reconstructParameters(&dP, serialisedParams));
+
+ CPPUNIT_ASSERT(dP->areOfType(DHParameters::type));
+
+ DHParameters* ddP = (DHParameters*) dP;
+
+ CPPUNIT_ASSERT(p->getP() == ddP->getP());
+ CPPUNIT_ASSERT(p->getG() == ddP->getG());
+ CPPUNIT_ASSERT(p->getXBitLength() == ddP->getXBitLength());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kp, dP));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(dh->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ DHPrivateKey* privKey = (DHPrivateKey*) kp->getPrivateKey();
+ DHPublicKey* pubKey = (DHPublicKey*) kp->getPublicKey();
+
+ DHPrivateKey* dPrivKey = (DHPrivateKey*) dKP->getPrivateKey();
+ DHPublicKey* dPubKey = (DHPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getP() == dPrivKey->getP());
+ CPPUNIT_ASSERT(privKey->getG() == dPrivKey->getG());
+ CPPUNIT_ASSERT(privKey->getX() == dPrivKey->getX());
+
+ CPPUNIT_ASSERT(pubKey->getP() == dPubKey->getP());
+ CPPUNIT_ASSERT(pubKey->getG() == dPubKey->getG());
+ CPPUNIT_ASSERT(pubKey->getY() == dPubKey->getY());
+
+ dh->recycleParameters(p);
+ dh->recycleParameters(dP);
+ dh->recycleKeyPair(kp);
+ dh->recycleKeyPair(dKP);
+}
+
+void DHTests::testPKCS8()
+{
+ // Generate 1024-bit parameters for testing
+ AsymmetricParameters* p;
+
+ CPPUNIT_ASSERT(dh->generateParameters(&p, (void*) 1024));
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kp, p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ DHPrivateKey* priv = (DHPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ DHPrivateKey* dPriv = (DHPrivateKey*) dh->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+
+ CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
+ CPPUNIT_ASSERT(priv->getG() == dPriv->getG());
+ CPPUNIT_ASSERT(priv->getX() == dPriv->getX());
+
+ dh->recycleParameters(p);
+ dh->recycleKeyPair(kp);
+ dh->recyclePrivateKey(dPriv);
+}
+
+void DHTests::testDerivation()
+{
+ AsymmetricKeyPair* kpa;
+ AsymmetricKeyPair* kpb;
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ // Generate parameters
+ AsymmetricParameters* p;
+
+ CPPUNIT_ASSERT(dh->generateParameters(&p, (void*) *k));
+
+ // Generate key-pairs
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kpa, p));
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kpb, p));
+
+ // Derive secrets
+ SymmetricKey* sa;
+ CPPUNIT_ASSERT(dh->deriveKey(&sa, kpb->getPublicKey(), kpa->getPrivateKey()));
+ SymmetricKey* sb;
+ CPPUNIT_ASSERT(dh->deriveKey(&sb, kpa->getPublicKey(), kpb->getPrivateKey()));
+
+ // Must be the same
+ CPPUNIT_ASSERT(sa->getKeyBits() == sb->getKeyBits());
+
+ // Clean up
+ dh->recycleSymmetricKey(sa);
+ dh->recycleSymmetricKey(sb);
+ dh->recycleKeyPair(kpa);
+ dh->recycleKeyPair(kpb);
+ dh->recycleParameters(p);
+ }
+}
+
+void DHTests::testDeriveKnownVector()
+{
+ // TODO
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/test/DHTests.h b/SoftHSMv2/src/lib/crypto/test/DHTests.h
new file mode 100644
index 0000000..e2a58ac
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DHTests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHTests.h
+
+ Contains test cases to test the DH class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DHTESTS_H
+#define _SOFTHSM_V2_DHTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class DHTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(DHTests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testDerivation);
+ CPPUNIT_TEST(testDeriveKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testDerivation();
+ void testDeriveKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // DH instance
+ AsymmetricAlgorithm* dh;
+};
+
+#endif // !_SOFTHSM_V2_DHTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/DSATests.cpp b/SoftHSMv2/src/lib/crypto/test/DSATests.cpp
new file mode 100644
index 0000000..80f2514
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DSATests.cpp
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSATests.cpp
+
+ Contains test cases to test the RNG class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "DSATests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#include "DSAParameters.h"
+#include "DSAPublicKey.h"
+#include "DSAPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DSATests);
+
+void DSATests::setUp()
+{
+ dsa = NULL;
+
+ dsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
+
+ // Check the DSA object
+ CPPUNIT_ASSERT(dsa != NULL);
+}
+
+void DSATests::tearDown()
+{
+ if (dsa != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
+ }
+
+ fflush(stdout);
+}
+
+void DSATests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+#ifndef WITH_FIPS
+ keySizes.push_back(1024);
+ keySizes.push_back(1536);
+#else
+ keySizes.push_back(1024);
+#endif
+#ifndef WITH_BOTAN
+ keySizes.push_back(2048);
+#endif
+
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ // Generate parameters
+ DSAParameters* p;
+ AsymmetricParameters** ap = (AsymmetricParameters**) &p;
+
+ CPPUNIT_ASSERT(dsa->generateParameters(ap, (void*) *k));
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(dsa->generateKeyPair(&kp, p));
+
+ DSAPublicKey* pub = (DSAPublicKey*) kp->getPublicKey();
+ DSAPrivateKey* priv = (DSAPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getBitLength() == *k);
+ CPPUNIT_ASSERT(priv->getBitLength() == *k);
+
+ dsa->recycleParameters(p);
+ dsa->recycleKeyPair(kp);
+ }
+}
+
+void DSATests::testSerialisation()
+{
+ // Generate 1024-bit parameters for testing
+ DSAParameters* p;
+ AsymmetricParameters** ap = (AsymmetricParameters**) &p;
+
+ CPPUNIT_ASSERT(dsa->generateParameters(ap, (void*) 1024));
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dP;
+
+ CPPUNIT_ASSERT(dsa->reconstructParameters(&dP, serialisedParams));
+
+ CPPUNIT_ASSERT(dP->areOfType(DSAParameters::type));
+
+ DSAParameters* ddP = (DSAParameters*) dP;
+
+ CPPUNIT_ASSERT(p->getP() == ddP->getP());
+ CPPUNIT_ASSERT(p->getQ() == ddP->getQ());
+ CPPUNIT_ASSERT(p->getG() == ddP->getG());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(dsa->generateKeyPair(&kp, dP));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(dsa->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ DSAPrivateKey* privKey = (DSAPrivateKey*) kp->getPrivateKey();
+ DSAPublicKey* pubKey = (DSAPublicKey*) kp->getPublicKey();
+
+ DSAPrivateKey* dPrivKey = (DSAPrivateKey*) dKP->getPrivateKey();
+ DSAPublicKey* dPubKey = (DSAPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getP() == dPrivKey->getP());
+ CPPUNIT_ASSERT(privKey->getQ() == dPrivKey->getQ());
+ CPPUNIT_ASSERT(privKey->getG() == dPrivKey->getG());
+ CPPUNIT_ASSERT(privKey->getX() == dPrivKey->getX());
+
+ CPPUNIT_ASSERT(pubKey->getP() == dPubKey->getP());
+ CPPUNIT_ASSERT(pubKey->getQ() == dPubKey->getQ());
+ CPPUNIT_ASSERT(pubKey->getG() == dPubKey->getG());
+ CPPUNIT_ASSERT(pubKey->getY() == dPubKey->getY());
+
+ dsa->recycleParameters(p);
+ dsa->recycleParameters(dP);
+ dsa->recycleKeyPair(kp);
+ dsa->recycleKeyPair(dKP);
+}
+
+void DSATests::testPKCS8()
+{
+ // Generate 1024-bit parameters for testing
+ AsymmetricParameters* p;
+
+ CPPUNIT_ASSERT(dsa->generateParameters(&p, (void*) 1024));
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(dsa->generateKeyPair(&kp, p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ DSAPrivateKey* priv = (DSAPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ DSAPrivateKey* dPriv = (DSAPrivateKey*) dsa->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+ CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
+ CPPUNIT_ASSERT(priv->getQ() == dPriv->getQ());
+ CPPUNIT_ASSERT(priv->getG() == dPriv->getG());
+ CPPUNIT_ASSERT(priv->getX() == dPriv->getX());
+
+ dsa->recycleParameters(p);
+ dsa->recycleKeyPair(kp);
+ dsa->recyclePrivateKey(dPriv);
+}
+
+void DSATests::testSigningVerifying()
+{
+ AsymmetricKeyPair* kp;
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+#ifndef WITH_FIPS
+ keySizes.push_back(1024);
+ keySizes.push_back(1536);
+#else
+ keySizes.push_back(1024);
+#endif
+#ifndef WITH_BOTAN
+ keySizes.push_back(2048);
+#endif
+
+ // Mechanisms to test
+ std::vector<AsymMech::Type> mechanisms;
+ mechanisms.push_back(AsymMech::DSA_SHA1);
+ mechanisms.push_back(AsymMech::DSA_SHA224);
+ mechanisms.push_back(AsymMech::DSA_SHA256);
+
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ // Generate parameters
+ AsymmetricParameters* p;
+
+ CPPUNIT_ASSERT(dsa->generateParameters(&p, (void*) *k));
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(dsa->generateKeyPair(&kp, p));
+
+ // Generate some data to sign
+ ByteString dataToSign;
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));
+
+ // Test mechanisms that perform internal hashing
+ for (std::vector<AsymMech::Type>::iterator m = mechanisms.begin(); m != mechanisms.end(); m++)
+ {
+ ByteString blockSignature, singlePartSignature;
+
+ // Sign the data in blocks
+ CPPUNIT_ASSERT(dsa->signInit(kp->getPrivateKey(), *m));
+ CPPUNIT_ASSERT(dsa->signUpdate(dataToSign.substr(0, 134)));
+ CPPUNIT_ASSERT(dsa->signUpdate(dataToSign.substr(134, 289)));
+ CPPUNIT_ASSERT(dsa->signUpdate(dataToSign.substr(134 + 289)));
+ CPPUNIT_ASSERT(dsa->signFinal(blockSignature));
+
+ // Sign the data in one pass
+ CPPUNIT_ASSERT(dsa->sign(kp->getPrivateKey(), dataToSign, singlePartSignature, *m));
+
+ // Now perform multi-pass verification
+ CPPUNIT_ASSERT(dsa->verifyInit(kp->getPublicKey(), *m));
+ CPPUNIT_ASSERT(dsa->verifyUpdate(dataToSign.substr(0, 125)));
+ CPPUNIT_ASSERT(dsa->verifyUpdate(dataToSign.substr(125, 247)));
+ CPPUNIT_ASSERT(dsa->verifyUpdate(dataToSign.substr(125 + 247)));
+ CPPUNIT_ASSERT(dsa->verifyFinal(blockSignature));
+
+ // And single-pass verification
+ CPPUNIT_ASSERT(dsa->verify(kp->getPublicKey(), dataToSign, singlePartSignature, *m));
+ }
+
+ // Test mechanisms that do not perform internal hashing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, *k >= 2048 ? 32 : 20));
+
+ // Sign the data
+ ByteString signature;
+ CPPUNIT_ASSERT(dsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::DSA));
+
+ // Verify the signature
+ CPPUNIT_ASSERT(dsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::DSA));
+
+ dsa->recycleKeyPair(kp);
+ dsa->recycleParameters(p);
+ }
+}
+
+void DSATests::testSignVerifyKnownVector()
+{
+ DSAPublicKey* pubKey1 = (DSAPublicKey*) dsa->newPublicKey();
+ DSAPublicKey* pubKey2 = (DSAPublicKey*) dsa->newPublicKey();
+ DSAPrivateKey* privKey1 = (DSAPrivateKey*) dsa->newPrivateKey();
+ DSAPrivateKey* privKey2 = (DSAPrivateKey*) dsa->newPrivateKey();
+
+ // Reconstruct public and private key #1
+ ByteString p1 = "e0a67598cd1b763bc98c8abb333e5dda0cd3aa0e5e1fb5ba8a7b4eabc10ba338fae06dd4b90fda70d7cf0cb0c638be3341bec0af8a7330a3307ded2299a0ee606df035177a239c34a912c202aa5f83b9c4a7cf0235b5316bfc6efb9a248411258b30b839af172440f32563056cb67a861158ddd90e6a894c72a5bbef9e286c6b";
+ ByteString q1 = "e950511eab424b9a19a2aeb4e159b7844c589c4f";
+ ByteString g1 = "d29d5121b0423c2769ab21843e5a3240ff19cacc792264e3bb6be4f78edd1b15c4dff7f1d905431f0ab16790e1f773b5ce01c804e509066a9919f5195f4abc58189fd9ff987389cb5bedf21b4dab4f8b76a055ffe2770988fe2ec2de11ad92219f0b351869ac24da3d7ba87011a701ce8ee7bfe49486ed4527b7186ca4610a75";
+ ByteString x1 = "d0ec4e50bb290a42e9e355c73d8809345de2e139";
+ ByteString y1 = "25282217f5730501dd8dba3edfcf349aaffec20921128d70fac44110332201bba3f10986140cbb97c726938060473c8ec97b4731db004293b5e730363609df9780f8d883d8c4d41ded6a2f1e1bbbdc979e1b9d6d3c940301f4e978d65b19041fcf1e8b518f5c0576c770fe5a7a485d8329ee2914a2de1b5da4a6128ceab70f79";
+
+ pubKey1->setP(p1);
+ pubKey1->setQ(q1);
+ pubKey1->setG(g1);
+ pubKey1->setY(y1);
+ privKey1->setP(p1);
+ privKey1->setQ(q1);
+ privKey1->setG(g1);
+ privKey1->setX(x1);
+
+ // Test with key #1
+ ByteString data1 = "616263"; // "abc"
+ ByteString goodSignature1 = "636155ac9a4633b4665d179f9e4117df68601f346c540b02d9d4852f89df8cfc99963204f4347704";
+ ByteString badSignature1 = "636155ac9a4633b4665d179f9e4117df68601f346c540b02d9d4852f89df8cfc99963204f4347705";
+
+ // Reconstruct public and private key #2
+ ByteString p2 = "f56c2a7d366e3ebdeaa1891fd2a0d099436438a673fed4d75f594959cffebca7be0fc72e4fe67d91d801cba0693ac4ed9e411b41d19e2fd1699c4390ad27d94c69c0b143f1dc88932cfe2310c886412047bd9b1c7a67f8a25909132627f51a0c866877e672e555342bdf9355347dbd43b47156b2c20bad9d2b071bc2fdcf9757f75c168c5d9fc43131be162a0756d1bdec2ca0eb0e3b018a8b38d3ef2487782aeb9fbf99d8b30499c55e4f61e5c7dcee2a2bb55bd7f75fcdf00e48f2e8356bdb59d86114028f67b8e07b127744778aff1cf1399a4d679d92fde7d941c5c85c5d7bff91ba69f9489d531d1ebfa727cfda651390f8021719fa9f7216ceb177bd75";
+ ByteString q2 = "c24ed361870b61e0d367f008f99f8a1f75525889c89db1b673c45af5867cb467";
+ ByteString g2 = "8dc6cc814cae4a1c05a3e186a6fe27eaba8cdb133fdce14a963a92e809790cba096eaa26140550c129fa2b98c16e84236aa33bf919cd6f587e048c52666576db6e925c6cbe9b9ec5c16020f9a44c9f1c8f7a8e611c1f6ec2513ea6aa0b8d0f72fed73ca37df240db57bbb27431d618697b9e771b0b301d5df05955425061a30dc6d33bb6d2a32bd0a75a0a71d2184f506372abf84a56aeeea8eb693bf29a640345fa1298a16e85421b2208d00068a5a42915f82cf0b858c8fa39d43d704b6927e0b2f916304e86fb6a1b487f07d8139e428bb096c6d67a76ec0b8d4ef274b8a2cf556d279ad267ccef5af477afed029f485b5597739f5d0240f67c2d948a6279";
+ ByteString x2 = "0caf2ef547ec49c4f3a6fe6df4223a174d01f2c115d49a6f73437c29a2a8458c";
+ ByteString y2 = "2828003d7c747199143c370fdd07a2861524514acc57f63f80c38c2087c6b795b62de1c224bf8d1d1424e60ce3f5ae3f76c754a2464af292286d873a7a30b7eacbbc75aafde7191d9157598cdb0b60e0c5aa3f6ebe425500c611957dbf5ed35490714a42811fdcdeb19af2ab30beadff2907931cee7f3b55532cffaeb371f84f01347630eb227a419b1f3f558bc8a509d64a765d8987d493b007c4412c297caf41566e26faee475137ec781a0dc088a26c8804a98c23140e7c936281864b99571ee95c416aa38ceebb41fdbff1eb1d1dc97b63ce1355257627c8b0fd840ddb20ed35be92f08c49aea5613957d7e5c7a6d5a5834b4cb069e0831753ecf65ba02b";
+
+ pubKey2->setP(p2);
+ pubKey2->setQ(q2);
+ pubKey2->setG(g2);
+ pubKey2->setY(y2);
+ privKey2->setP(p2);
+ privKey2->setQ(q2);
+ privKey2->setG(g2);
+ privKey2->setX(x2);
+
+ // Test with key #2
+ ByteString data2 = "616263"; // "abc"
+ ByteString goodSignature2 = "315c875dcd4850e948b8ac42824e9483a32d5ba5abe0681b9b9448d444f2be3c89718d12e54a8d9ed066e4a55f7ed5a2229cd23b9a3cee78f83ed6aa61f6bcb9";
+ ByteString badSignature2 = "315c875dcd4850e948b8ac42824e9483a32d5ba5abe0681b9b9448d444f2be3c89718d12e54a8d9ed066e4a55f7ed5a2229cd23b9a3cee78f83ed6aa61f6bcb8";
+
+ CPPUNIT_ASSERT(dsa->verify(pubKey1, data1, goodSignature1, AsymMech::DSA_SHA1));
+ CPPUNIT_ASSERT(!dsa->verify(pubKey1, data1, badSignature1, AsymMech::DSA_SHA1));
+ CPPUNIT_ASSERT(dsa->verify(pubKey2, data2, goodSignature2, AsymMech::DSA_SHA256));
+ CPPUNIT_ASSERT(!dsa->verify(pubKey2, data2, badSignature2, AsymMech::DSA_SHA256));
+
+ dsa->recyclePublicKey(pubKey1);
+ dsa->recyclePublicKey(pubKey2);
+ dsa->recyclePrivateKey(privKey1);
+ dsa->recyclePrivateKey(privKey2);
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/DSATests.h b/SoftHSMv2/src/lib/crypto/test/DSATests.h
new file mode 100644
index 0000000..446733a
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DSATests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSATests.h
+
+ Contains test cases to test the DSA class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DSATESTS_H
+#define _SOFTHSM_V2_DSATESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class DSATests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(DSATests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testSigningVerifying);
+ CPPUNIT_TEST(testSignVerifyKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testSigningVerifying();
+ void testSignVerifyKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // DSA instance
+ AsymmetricAlgorithm* dsa;
+};
+
+#endif // !_SOFTHSM_V2_DSATESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/ECDHTests.cpp b/SoftHSMv2/src/lib/crypto/test/ECDHTests.cpp
new file mode 100644
index 0000000..1646fd8
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ECDHTests.cpp
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECDHTests.cpp
+
+ Contains test cases to test the ECDH class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "ECDHTests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#ifdef WITH_ECC
+#include "ECParameters.h"
+#include "ECPublicKey.h"
+#include "ECPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ECDHTests);
+
+void ECDHTests::setUp()
+{
+ ecdh = NULL;
+
+ ecdh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDH);
+
+ // Check the ECDH object
+ CPPUNIT_ASSERT(ecdh != NULL);
+}
+
+void ECDHTests::tearDown()
+{
+ if (ecdh != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
+ }
+
+ fflush(stdout);
+}
+
+void ECDHTests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Curves to test
+ std::vector<ByteString> curves;
+ // Add X9.62 prime256v1
+ curves.push_back(ByteString("06082a8648ce3d030107"));
+ // Add secp384r1
+ curves.push_back(ByteString("06052b81040022"));
+
+ for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++)
+ {
+ // Set domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(*c);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kp, p));
+
+ ECPublicKey* pub = (ECPublicKey*) kp->getPublicKey();
+ ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getEC() == *c);
+ CPPUNIT_ASSERT(priv->getEC() == *c);
+
+ ecdh->recycleParameters(p);
+ ecdh->recycleKeyPair(kp);
+ }
+}
+
+void ECDHTests::testSerialisation()
+{
+ // Get prime256v1 domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06082a8648ce3d030107"));
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dEC;
+
+ CPPUNIT_ASSERT(ecdh->reconstructParameters(&dEC, serialisedParams));
+
+ CPPUNIT_ASSERT(dEC->areOfType(ECParameters::type));
+
+ ECParameters* ddEC = (ECParameters*) dEC;
+
+ CPPUNIT_ASSERT(p->getEC() == ddEC->getEC());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kp, dEC));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(ecdh->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ ECPrivateKey* privKey = (ECPrivateKey*) kp->getPrivateKey();
+ ECPublicKey* pubKey = (ECPublicKey*) kp->getPublicKey();
+
+ ECPrivateKey* dPrivKey = (ECPrivateKey*) dKP->getPrivateKey();
+ ECPublicKey* dPubKey = (ECPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getEC() == dPrivKey->getEC());
+ CPPUNIT_ASSERT(privKey->getD() == dPrivKey->getD());
+
+ CPPUNIT_ASSERT(pubKey->getEC() == dPubKey->getEC());
+ CPPUNIT_ASSERT(pubKey->getQ() == dPubKey->getQ());
+
+ ecdh->recycleParameters(p);
+ ecdh->recycleParameters(dEC);
+ ecdh->recycleKeyPair(kp);
+ ecdh->recycleKeyPair(dKP);
+}
+
+void ECDHTests::testPKCS8()
+{
+ // Get prime256v1 domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06082a8648ce3d030107"));
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kp, p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ ECPrivateKey* dPriv = (ECPrivateKey*) ecdh->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+ CPPUNIT_ASSERT(priv->getEC() == dPriv->getEC());
+ CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
+
+ ecdh->recycleParameters(p);
+ ecdh->recycleKeyPair(kp);
+ ecdh->recyclePrivateKey(dPriv);
+}
+
+void ECDHTests::testDerivation()
+{
+ AsymmetricKeyPair* kpa;
+ AsymmetricKeyPair* kpb;
+ ECParameters* p;
+
+ // Curves to test
+ std::vector<ByteString> curves;
+ // Add X9.62 prime256v1
+ curves.push_back(ByteString("06082a8648ce3d030107"));
+ // Add secp384r1
+ curves.push_back(ByteString("06052b81040022"));
+
+ for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++)
+ {
+ // Get parameters
+ p = new ECParameters;
+ CPPUNIT_ASSERT(p != NULL);
+ p->setEC(*c);
+
+ // Generate key-pairs
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kpa, p));
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kpb, p));
+
+ // Derive secrets
+ SymmetricKey* sa;
+ CPPUNIT_ASSERT(ecdh->deriveKey(&sa, kpb->getPublicKey(), kpa->getPrivateKey()));
+ SymmetricKey* sb;
+ CPPUNIT_ASSERT(ecdh->deriveKey(&sb, kpa->getPublicKey(), kpb->getPrivateKey()));
+
+ // Must be the same
+ CPPUNIT_ASSERT(sa->getKeyBits() == sb->getKeyBits());
+
+ // Clean up
+ ecdh->recycleSymmetricKey(sa);
+ ecdh->recycleSymmetricKey(sb);
+ ecdh->recycleKeyPair(kpa);
+ ecdh->recycleKeyPair(kpb);
+ ecdh->recycleParameters(p);
+ }
+}
+
+void ECDHTests::testDeriveKnownVector()
+{
+ ECPublicKey* pubKeya = (ECPublicKey*) ecdh->newPublicKey();
+ ECPublicKey* pubKeyb = (ECPublicKey*) ecdh->newPublicKey();
+ ECPrivateKey* privKeya = (ECPrivateKey*) ecdh->newPrivateKey();
+ ECPrivateKey* privKeyb = (ECPrivateKey*) ecdh->newPrivateKey();
+
+ // Reconstruct public and private key for Alice
+ ByteString ec = "06082a8648ce3d030107"; // X9.62 prime256v1
+ ByteString da = "c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433";
+ // add 04 (ASN_String) <len+1> 04 (UNCOMPRESSED) in front!
+ ByteString qa = "044104dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3";
+
+ pubKeya->setEC(ec);
+ pubKeya->setQ(qa);
+ privKeya->setEC(ec);
+ privKeya->setD(da);
+
+ // Reconstruct public and private key for Bob
+ ByteString db = "c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0b283ab46476bee53";
+ ByteString qb = "044104d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab";
+
+ pubKeyb->setEC(ec);
+ pubKeyb->setQ(qb);
+ privKeyb->setEC(ec);
+ privKeyb->setD(db);
+
+ // Test
+ ByteString expected = "d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de";
+ SymmetricKey* sa;
+ CPPUNIT_ASSERT(ecdh->deriveKey(&sa, pubKeya, privKeyb));
+ CPPUNIT_ASSERT(sa->getKeyBits() == expected);
+ SymmetricKey* sb;
+ CPPUNIT_ASSERT(ecdh->deriveKey(&sb, pubKeyb, privKeya));
+ CPPUNIT_ASSERT(sb->getKeyBits() == expected);
+
+ ecdh->recyclePublicKey(pubKeya);
+ ecdh->recyclePublicKey(pubKeyb);
+ ecdh->recyclePrivateKey(privKeya);
+ ecdh->recyclePrivateKey(privKeyb);
+ ecdh->recycleSymmetricKey(sa);
+ ecdh->recycleSymmetricKey(sb);
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/test/ECDHTests.h b/SoftHSMv2/src/lib/crypto/test/ECDHTests.h
new file mode 100644
index 0000000..81cf6d5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ECDHTests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECDHTests.h
+
+ Contains test cases to test the ECDH class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ECDHTESTS_H
+#define _SOFTHSM_V2_ECDHTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class ECDHTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(ECDHTests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testDerivation);
+ CPPUNIT_TEST(testDeriveKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testDerivation();
+ void testDeriveKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // ECDH instance
+ AsymmetricAlgorithm* ecdh;
+};
+
+#endif // !_SOFTHSM_V2_ECDHTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/ECDSATests.cpp b/SoftHSMv2/src/lib/crypto/test/ECDSATests.cpp
new file mode 100644
index 0000000..3c29d06
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ECDSATests.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECDSATests.cpp
+
+ Contains test cases to test the ECDSA class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <utility>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "ECDSATests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#ifdef WITH_ECC
+#include "ECParameters.h"
+#include "ECPublicKey.h"
+#include "ECPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ECDSATests);
+
+void ECDSATests::setUp()
+{
+ ecdsa = NULL;
+
+ ecdsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
+
+ // Check the ECDSA object
+ CPPUNIT_ASSERT(ecdsa != NULL);
+}
+
+void ECDSATests::tearDown()
+{
+ if (ecdsa != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdsa);
+ }
+
+ fflush(stdout);
+}
+
+void ECDSATests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Curves to test
+ std::vector<ByteString> curves;
+ // Add X9.62 prime256v1
+ curves.push_back(ByteString("06082a8648ce3d030107"));
+ // Add secp384r1
+ curves.push_back(ByteString("06052b81040022"));
+ // Add secp521r1
+ curves.push_back(ByteString("06052b81040023"));
+
+ for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++)
+ {
+ // Set domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(*c);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(ecdsa->generateKeyPair(&kp, p));
+
+ ECPublicKey* pub = (ECPublicKey*) kp->getPublicKey();
+ ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getEC() == *c);
+ CPPUNIT_ASSERT(priv->getEC() == *c);
+
+ ecdsa->recycleParameters(p);
+ ecdsa->recycleKeyPair(kp);
+ }
+}
+
+void ECDSATests::testSerialisation()
+{
+ // Get prime256v1 domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06082a8648ce3d030107"));
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dEC;
+
+ CPPUNIT_ASSERT(ecdsa->reconstructParameters(&dEC, serialisedParams));
+
+ CPPUNIT_ASSERT(dEC->areOfType(ECParameters::type));
+
+ ECParameters* ddEC = (ECParameters*) dEC;
+
+ CPPUNIT_ASSERT(p->getEC() == ddEC->getEC());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(ecdsa->generateKeyPair(&kp, dEC));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(ecdsa->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ ECPrivateKey* privKey = (ECPrivateKey*) kp->getPrivateKey();
+ ECPublicKey* pubKey = (ECPublicKey*) kp->getPublicKey();
+
+ ECPrivateKey* dPrivKey = (ECPrivateKey*) dKP->getPrivateKey();
+ ECPublicKey* dPubKey = (ECPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getEC() == dPrivKey->getEC());
+ CPPUNIT_ASSERT(privKey->getD() == dPrivKey->getD());
+
+ CPPUNIT_ASSERT(pubKey->getEC() == dPubKey->getEC());
+ CPPUNIT_ASSERT(pubKey->getQ() == dPubKey->getQ());
+
+ ecdsa->recycleParameters(p);
+ ecdsa->recycleParameters(dEC);
+ ecdsa->recycleKeyPair(kp);
+ ecdsa->recycleKeyPair(dKP);
+}
+
+void ECDSATests::testPKCS8()
+{
+ // Get prime256v1 domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06082a8648ce3d030107"));
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(ecdsa->generateKeyPair(&kp, p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ ECPrivateKey* dPriv = (ECPrivateKey*) ecdsa->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+ CPPUNIT_ASSERT(priv->getEC() == dPriv->getEC());
+ CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
+
+ ecdsa->recycleParameters(p);
+ ecdsa->recycleKeyPair(kp);
+ ecdsa->recyclePrivateKey(dPriv);
+}
+
+void ECDSATests::testSigningVerifying()
+{
+ AsymmetricKeyPair* kp;
+ ECParameters *p;
+
+ // Curves/Hashes to test
+ std::vector<std::pair<ByteString, HashAlgo::Type> > totest;
+ // Add X9.62 prime256v1
+ totest.push_back(std::make_pair(ByteString("06082a8648ce3d030107"), HashAlgo::SHA256));
+ // Add secp384r1
+ totest.push_back(std::make_pair(ByteString("06052b81040022"), HashAlgo::SHA384));
+ // Add secp521r1
+ totest.push_back(std::make_pair(ByteString("06052b81040023"), HashAlgo::SHA384));
+
+ for (std::vector<std::pair<ByteString, HashAlgo::Type> >::iterator k = totest.begin(); k != totest.end(); k++)
+ {
+ // Get parameters
+ p = new ECParameters;
+ CPPUNIT_ASSERT(p != NULL);
+ p->setEC(k->first);
+ HashAlgorithm *hash;
+ hash = CryptoFactory::i()->getHashAlgorithm(k->second);
+ CPPUNIT_ASSERT(hash != NULL);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(ecdsa->generateKeyPair(&kp, p));
+
+ // Generate some data to sign
+ ByteString dataToSign;
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+ CPPUNIT_ASSERT(rng != NULL);
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));
+
+ // Sign the data
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(dataToSign));
+ ByteString hResult;
+ CPPUNIT_ASSERT(hash->hashFinal(hResult));
+ ByteString sig;
+ CPPUNIT_ASSERT(ecdsa->sign(kp->getPrivateKey(), hResult, sig, AsymMech::ECDSA));
+
+ // And verify it
+ CPPUNIT_ASSERT(ecdsa->verify(kp->getPublicKey(), hResult, sig, AsymMech::ECDSA));
+
+ ecdsa->recycleKeyPair(kp);
+ ecdsa->recycleParameters(p);
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ }
+}
+
+void ECDSATests::testSignVerifyKnownVector()
+{
+ ECPublicKey* pubKey1 = (ECPublicKey*) ecdsa->newPublicKey();
+ ECPublicKey* pubKey2 = (ECPublicKey*) ecdsa->newPublicKey();
+ ECPrivateKey* privKey1 = (ECPrivateKey*) ecdsa->newPrivateKey();
+ ECPrivateKey* privKey2 = (ECPrivateKey*) ecdsa->newPrivateKey();
+ HashAlgorithm* hash1 = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA256);
+ HashAlgorithm* hash2 = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA384);
+
+ // Reconstruct public and private key #1
+ ByteString ec1 = "06082a8648ce3d030107"; // X9.62 prime256v1
+ ByteString d1 = "dc51d3866a15bacde33d96f992fca99da7e6ef0934e7097559c27f1614c88a7f";
+ // add 04 (ASN_String) <len+1> 04 (UNCOMPRESSED) in front!
+ ByteString q1 = "0441042442a5cc0ecd015fa3ca31dc8e2bbc70bf42d60cbca20085e0822cb04235e9706fc98bd7e50211a4a27102fa3549df79ebcb4bf246b80945cddfe7d509bbfd7d";
+
+ pubKey1->setEC(ec1);
+ pubKey1->setQ(q1);
+ privKey1->setEC(ec1);
+ privKey1->setD(d1);
+ CPPUNIT_ASSERT(hash1 != NULL);
+
+ // Test with key #1
+ ByteString data1 = "616263"; // "abc"
+ ByteString goodSignature1 = "cb28e0999b9c7715fd0a80d8e47a77079716cbbf917dd72e97566ea1c066957c86fa3bb4e26cad5bf90b7f81899256ce7594bb1ea0c89212748bff3b3d5b0315";
+ ByteString badSignature1 = "cb28e0999b9c7715fd0a80d8e47a77079716cbbf917dd72e97566ea1c066957c86fa3bb4e26cad5bf90b7f81899256ce7594bb1ea0c89212748bff3b3d5b0316";
+
+ // Reconstruct public and private key #2
+ ByteString ec2 = "06052b81040022"; // secp384r1
+ ByteString d2 = "0beb646634ba87735d77ae4809a0ebea865535de4c1e1dcb692e84708e81a5af62e528c38b2a81b35309668d73524d9f";
+ // add 04 (ASN_String) <len+1> 04 (UNCOMPRESSED) in front!
+ ByteString q2 = "04610496281bf8dd5e0525ca049c048d345d3082968d10fedf5c5aca0c64e6465a97ea5ce10c9dfec21797415710721f437922447688ba94708eb6e2e4d59f6ab6d7edff9301d249fe49c33096655f5d502fad3d383b91c5e7edaa2b714cc99d5743ca";
+
+ pubKey2->setEC(ec2);
+ pubKey2->setQ(q2);
+ privKey2->setEC(ec2);
+ privKey2->setD(d2);
+ CPPUNIT_ASSERT(hash2 != NULL);
+
+ // Test with key #2
+ ByteString data2 = "616263"; // "abc"
+ ByteString goodSignature2 = "fb017b914e29149432d8bac29a514640b46f53ddab2c69948084e2930f1c8f7e08e07c9c63f2d21a07dcb56a6af56eb3b263a1305e057f984d38726a1b46874109f417bca112674c528262a40a629af1cbb9f516ce0fa7d2ff630863a00e8b9f";
+ ByteString badSignature2 = "fb017b914e29149432d8bac29a514640b46f53ddab2c69948084e2930f1c8f7e08e07c9c63f2d21a07dcb56a6af56eb3b263a1305e057f984d38726a1b46874109f417bca112674c528262a40a629af1cbb9f516ce0fa7d2ff630863a00e8b9e";
+
+ CPPUNIT_ASSERT(hash1->hashInit());
+ CPPUNIT_ASSERT(hash1->hashUpdate(data1));
+ ByteString hResult1;
+ CPPUNIT_ASSERT(hash1->hashFinal(hResult1));
+ CPPUNIT_ASSERT(ecdsa->verify(pubKey1, hResult1, goodSignature1, AsymMech::ECDSA));
+ CPPUNIT_ASSERT(!ecdsa->verify(pubKey1, hResult1, badSignature1, AsymMech::ECDSA));
+ CPPUNIT_ASSERT(hash2->hashInit());
+ CPPUNIT_ASSERT(hash2->hashUpdate(data2));
+ ByteString hResult2;
+ CPPUNIT_ASSERT(hash2->hashFinal(hResult2));
+ CPPUNIT_ASSERT(ecdsa->verify(pubKey2, hResult2, goodSignature2, AsymMech::ECDSA));
+ CPPUNIT_ASSERT(!ecdsa->verify(pubKey2, hResult2, badSignature2, AsymMech::ECDSA));
+
+ ecdsa->recyclePublicKey(pubKey1);
+ ecdsa->recyclePublicKey(pubKey2);
+ ecdsa->recyclePrivateKey(privKey1);
+ ecdsa->recyclePrivateKey(privKey2);
+ CryptoFactory::i()->recycleHashAlgorithm(hash1);
+ CryptoFactory::i()->recycleHashAlgorithm(hash2);
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/test/ECDSATests.h b/SoftHSMv2/src/lib/crypto/test/ECDSATests.h
new file mode 100644
index 0000000..70b3345
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ECDSATests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECDSATests.h
+
+ Contains test cases to test the ECDSA class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ECDSATESTS_H
+#define _SOFTHSM_V2_ECDSATESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class ECDSATests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(ECDSATests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testSigningVerifying);
+ CPPUNIT_TEST(testSignVerifyKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testSigningVerifying();
+ void testSignVerifyKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // ECDSA instance
+ AsymmetricAlgorithm* ecdsa;
+};
+
+#endif // !_SOFTHSM_V2_ECDSATESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/GOSTTests.cpp b/SoftHSMv2/src/lib/crypto/test/GOSTTests.cpp
new file mode 100644
index 0000000..91f6876
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/GOSTTests.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ GOSTTests.cpp
+
+ Contains test cases to test the GOST implementations
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "GOSTTests.h"
+#include "CryptoFactory.h"
+#include <stdio.h>
+#include "AsymmetricAlgorithm.h"
+#include "AsymmetricKeyPair.h"
+#include "HashAlgorithm.h"
+#include "MacAlgorithm.h"
+#include "RNG.h"
+#ifdef WITH_GOST
+#include "ECParameters.h"
+#include "GOSTPublicKey.h"
+#include "GOSTPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(GOSTTests);
+
+void GOSTTests::setUp()
+{
+ hash = NULL;
+ mac = NULL;
+ gost = NULL;
+ rng = NULL;
+
+ gost = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
+
+ // Check the GOST object
+ CPPUNIT_ASSERT(gost != NULL);
+}
+
+void GOSTTests::tearDown()
+{
+ if (hash != NULL)
+ {
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ }
+
+ if (mac != NULL)
+ {
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+ }
+
+ if (gost != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(gost);
+ }
+
+ fflush(stdout);
+}
+
+void GOSTTests::testHash()
+{
+ char testData[4096] = "FE5A773751EAB2F18921C04806D6907444557B4469CDA7C822288E5065DA58F448A27FA0B4C8786853F246B093E3DBFDC332759D7764B6D057895184D9B82E626DF70AEB99B969EA35E5BE4D50C7406EA4A7450AC063933F96F77960EE711A445593119CF69061702CB4797F214FA440C94127E3DCD92F2C71B39D354C6F4284E030DCBFCB91EA5E543E0E3560ECD355091850BA080287BD87B74BB84A8892E0F2172F136D187305179F23EB8296BF1798405BAB52E201F22BCA5B793C5BA6F2CA15F154598EEC73E7E61B405262F6FE5FDC0F9AE0528801C3F965956C79A6C6805EDD0C6515AEA27D1DB9D70A56B0F13A544429C448FB6DB390C0E367EDF997E0B681ADE3846D77D1898F06FB60CB2384015F3749BD1E8163E532529E4D3BB8B200BBE79DA76D4865621FF2E583A1A1F8EBFB7A51B65DC9152B173A7DF91C6943F2FE497CDBC306827146199ADA925DD42B8A48429F5B6E3670AA85A44BDFAB3D273EA6711B996B5C27E04949BE61ED9ECB932F429ADCF31A2E0E9F83FCB1CE6BC0EE81627D1F9D08ECD599F16A1D68B256B002E90A8B4E5830A049ECE9ADF1D50C027EC537DD5412AA1509E91CEF358B2D495D3B37651987F51D9643A5AF2E0EF3D8C02E6023BB76FF8F1EB5CD018FA32BD7886A1A46A7D5CA15E4E0CDB793F0C1986EF4480305801A518B1D4596AAA741C093FC7AD075B637B1B2CC4DA33B6EB6D549001B33E1753C9C4358FB541FDE6541238BD011CD8ACAFB4CFF15B289872956DFBCC732593E838B6300E48ED3455CD101920114640A5B7C1250E419B7D771EC65934F53176BBD7A61A36D6D3D64A1F29C3D41745993636F812930E2936E9ED34E92A3C31239176ED3F78461EE80C54D92CBD9EF9F5746F8069809A38549FC7A8FD99FB350C27230966D6001D3136114A7BDCDEE495B72E4A633845BC88400DEDADC2FA2CD8640049CDB4F8F695C45EACF24FD573E1FB1670F688C9D7706A9AE9EB30E0DFDD54C7F3F3EE6F9BBFBBED6DB6E7C7B979E677DCD8457949DC271BD6ACB445B16247D8DAC1B59D45B8FFBBFDAEA20A5C450E0F93B399AE69887E1C721B0EF86C8CD37FC7514C4F2B70AA1E757DE95DCC3B74C6E18E51D272D433330826435B7CBA6C099558B51E408B1BFE60E876141A74195A00BF914F2536D92170FB43E078D98F784E6F150ED2B16DB5B629EBABF16444639C87A544050E03FB7CCD538DA29C45CE764F68682B48BF8AE5ED43064E833338A88605B1743FEB025D5F5607BB13A2078A99924A2D4818CD582ACDC1556FAEBA70959DE8498F3FCBF85BD269A7DF23A3AD5704908978031667C7BF4A85D1EF42F3ED144670E6EEB5D8213DB43B0B7B43767FD4277EF0EC52B5718A7D187A003DE8E5DFF9C3A3CD520615FB9B52281506E5BB033818E0912980A8BCAA54E21C5630B9E863C83";
+ char testResult[512] = "3EC65819A084AD30712C4B3EB69CE130A8C7221EA3D8A9996D4BA6F298BC39F9";
+
+ // Get a GOST R 34.11-94 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::GOST)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), gostHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(gostHash));
+
+ CPPUNIT_ASSERT(osslHash == gostHash);
+
+ // Now recreate the hash in a single part operation
+ gostHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(gostHash));
+
+ CPPUNIT_ASSERT(osslHash == gostHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void GOSTTests::testHmac()
+{
+ char testData[4096] = "1450414E94B2CEA9E202B8ACC9C358EBA5334C20CF1B7D13E8B79BE63A0A938A340CF710D539262F406787AF7188990C7D75780C265E37750510FA6AAA742D01C753548219C20B1283CCA9D30AA5A8650D0C5EE63FE10268F9CD5996F8DB0158C6FAD147AE41C0E565F6FBC85115E17BB0B448208075D1CF79CF70574098E7116A5C5EFFDB05DCD83E71DB4860B3AEC2612FB9DE1B010229A413055724AB07F4131B04800286D3C4895A158E7B1301F8010E718C76CC69B34C643D2B1EACC00F9CD0DEBC83425256B2524B34D61EBA32FE5F79FE0A1F9360E3CFB4C88CE7CC3C36E969A37827AD5FD79BFAC08CCA1786F30F34ADC605545F04BA96CA4A4E3DF7FEC36E43406E9CD68D708CBAC4C54B2E18E38535BD1A8029FD7393B5462AB688F8146445295E5473B15B26EC129A24C78B7198D558209E827C38426D747FB0D2B04F1EE7B142B7B736EFF4B819B5420F4642E77181617BEC8074109B463F4C53A6F3507A0B4419B2D7CC0B6CF89FAA2CAEAC17BF19E6A94E0BF346D0F77C47EDB29CBD204483E53853401779AEA0998B993E39EA4C5003326C017A5A3BD0C5591D4F822641FAE9DBDF78B15DC5BA326150F89C864774A8DBF6464B259A29C00D9BCC63F61B3B45FF19E6FD0CDA2BE17608488B0E5C6CC5C596F035C8E580C30FC7C6FE2428F3509511B9D7FE77CF53C5B0E8E66BB573B3D467B74B5493A4E8EA49A79B7E2D36A6C0A600C6B13DC617C3FAF927B2CB251279CFF4228254CB6022AE9D97A36894EBCB305B179284E5D2F330266B2B600E248D3C4B8121A8D698183A38BFB5A40C5E85CB08EF0BFB0242E418D11DD648B9B84E072A70D3FBA8A9B0CEE05BFD71AC945543E306824F9A4DCBA05BBE0027B475A020BD764B53AA5A187C089A2DEF8F3A96D38491A61CE5F3DA625F7F4EF38130B0F5DAA14E2236F4CD95FF0C31E7D6C1CC15CDE7D9D4F95326AE721812458D413CD6C758671C9A85D10F7692CE31A600483F6444F45E74C45B7CF886E63D0158E19C0B87BE6CD9FC4B74D72CB004D3BD7ADF60E162F4967E5EF3BCA0AF2DD7ED1DDE4097B5BA250281DB7E46C22A25A49ABDB1B2D148710128DC1F1A18CD0D762A1D2EB5D5D602336EE3F0A0095592E938A79BDEE72CF801015AD5871A8D907298E13F960A1417FDFA87C3FE3DA9490B73B45326C3161D9DE6460E37208665FDC90CF894A0301198F5FAA5A315FC562B2837194662A58DA13065760571172D42306BB57ECCFA578E9C927C211A1F7C1983DE1AE1EAB0A264AFDC18CD56F14E0429E80B0DDE9A5AF527952A7B6ABECFCB64CBDA3C3E7A024FC5CA3B655FAF5A2787FDB22C1DD3160827C886A119FD2833DA87E60F18B6A969916D35F559BCEA40D6E5E53F84FA5C46DD5DD09D0802A21F64F00EA755F95234AF913DBFB380CC370754448E46EDFC7CCC";
+ char testResult[512] = "8D9D660D7BCAB705F14A90CB9A31F7B5206F9936E1B56F2489DA188A90C49CA3";
+
+ // Get an HMAC GOST R34.11-94 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_GOST)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-GOST_R-34.11-94_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now verify the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now recreate the MAC in a single part operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate the MAC in a multiple part operation
+ shsmMac.wipe();
+
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Check if bad key is refused
+ osslMac[10] ^= 0x11;
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(!mac->verifyFinal(osslMac));
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+}
+
+void GOSTTests::testHashKnownVector()
+{
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::GOST)) != NULL);
+
+ // Message to hash for test #1
+ ByteString msg = "6d65737361676520646967657374"; // "message digest"
+ ByteString expected = "bc6041dd2aa401ebfa6e9886734174febdb4729aa972d60f549ac39b29721ba0";
+ ByteString result;
+
+ // Test #1
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(msg));
+ CPPUNIT_ASSERT(hash->hashFinal(result));
+
+ CPPUNIT_ASSERT(result == expected);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ hash = NULL;
+}
+
+void GOSTTests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Set domain parameters
+ ByteString curve = "06072a850302022301";
+ ECParameters* p = new ECParameters;
+ p->setEC(curve);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(gost->generateKeyPair(&kp, p));
+
+ GOSTPublicKey* pub = (GOSTPublicKey*) kp->getPublicKey();
+ GOSTPrivateKey* priv = (GOSTPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getQ().size() == 64);
+ CPPUNIT_ASSERT(priv->getD().size() == 32);
+
+ gost->recycleParameters(p);
+ gost->recycleKeyPair(kp);
+}
+
+void GOSTTests::testSerialisation()
+{
+ // Get GOST R 34.10-2001 params-A domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06072a850302022301"));
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dEC;
+
+ CPPUNIT_ASSERT(gost->reconstructParameters(&dEC, serialisedParams));
+
+ CPPUNIT_ASSERT(dEC->areOfType(ECParameters::type));
+
+ ECParameters* ddEC = (ECParameters*) dEC;
+
+ CPPUNIT_ASSERT(p->getEC() == ddEC->getEC());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(gost->generateKeyPair(&kp, dEC));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(gost->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ GOSTPrivateKey* privKey = (GOSTPrivateKey*) kp->getPrivateKey();
+ GOSTPublicKey* pubKey = (GOSTPublicKey*) kp->getPublicKey();
+
+ GOSTPrivateKey* dPrivKey = (GOSTPrivateKey*) dKP->getPrivateKey();
+ GOSTPublicKey* dPubKey = (GOSTPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getD() == dPrivKey->getD());
+ CPPUNIT_ASSERT(pubKey->getQ() == dPubKey->getQ());
+
+ gost->recycleParameters(p);
+ gost->recycleParameters(dEC);
+ gost->recycleKeyPair(kp);
+ gost->recycleKeyPair(dKP);
+}
+
+void GOSTTests::testSigningVerifying()
+{
+ AsymmetricKeyPair* kp;
+ ECParameters *p;
+ ByteString curve = "06072a850302022301";
+
+ // Get parameters
+ p = new ECParameters;
+ CPPUNIT_ASSERT(p != NULL);
+ p->setEC(curve);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(gost->generateKeyPair(&kp, p));
+
+ // Generate some data to sign
+ ByteString dataToSign;
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+ CPPUNIT_ASSERT(rng != NULL);
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));
+
+ // Sign the data
+ ByteString sig;
+ CPPUNIT_ASSERT(gost->sign(kp->getPrivateKey(), dataToSign, sig, AsymMech::GOST_GOST));
+
+ // And verify it
+ CPPUNIT_ASSERT(gost->verify(kp->getPublicKey(), dataToSign, sig, AsymMech::GOST_GOST));
+
+ gost->recycleKeyPair(kp);
+ gost->recycleParameters(p);
+}
+
+void GOSTTests::testSignVerifyKnownVector()
+{
+ // TODO
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/test/GOSTTests.h b/SoftHSMv2/src/lib/crypto/test/GOSTTests.h
new file mode 100644
index 0000000..f243392
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/GOSTTests.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ GOSTTests.h
+
+ Contains test cases to test the GOST implementations
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_HASHTESTS_H
+#define _SOFTHSM_V2_HASHTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+#include "HashAlgorithm.h"
+#include "MacAlgorithm.h"
+#include "RNG.h"
+
+class GOSTTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(GOSTTests);
+ CPPUNIT_TEST(testHash);
+ CPPUNIT_TEST(testHmac);
+ CPPUNIT_TEST(testHashKnownVector);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testSigningVerifying);
+ CPPUNIT_TEST(testSignVerifyKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testHash();
+ void testHmac();
+ void testHashKnownVector();
+ void testKeyGeneration();
+ void testSerialisation();
+ void testSigningVerifying();
+ void testSignVerifyKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ HashAlgorithm* hash;
+
+ MacAlgorithm* mac;
+
+ AsymmetricAlgorithm* gost;
+
+ RNG* rng;
+};
+
+#endif // !_SOFTHSM_V2_HASHTESTS_H
diff --git a/SoftHSMv2/src/lib/crypto/test/HashTests.cpp b/SoftHSMv2/src/lib/crypto/test/HashTests.cpp
new file mode 100644
index 0000000..f02adbc
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/HashTests.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ HashTests.cpp
+
+ Contains test cases to test the hash implementations
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "HashTests.h"
+#include "CryptoFactory.h"
+#include <stdio.h>
+#include "HashAlgorithm.h"
+#include "RNG.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(HashTests);
+
+void HashTests::setUp()
+{
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::tearDown()
+{
+ if (hash != NULL)
+ {
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ }
+
+ fflush(stdout);
+}
+
+#ifndef WITH_FIPS
+void HashTests::testMD5()
+{
+ char testData[4096] = "EDB39CC3CB5E8FD23A2182FAE8781F4E8E8534C8FE10BDC7ACDB34C4E22E4B60872E51AD092950771E475FB97B05D6203A0D1B3326D9678E44FB40787D8CF16BD3BBE4D4786F60BD8E9766EF1C30B22301FA8F7232358B3C5BE644342499622A5153B29D2E5F8F509771E8A5DE3B3737D30F2AB035262B8D83EC55F683E9B62BBB31E2E1F5E142A13ACB9701E1DE8752ACD492A943C2DB57CF4035BDA9D0519B86847CF74DB2F43CC23016D88EF44BA422710C00AEBB2ABDDED89D92E4BD132CEB87581644198B0D4AF82F3CE161ED03A4E189BE8276243243817F91159BDE294E61400041537618703754C609709846C3EDAE6922B498D24FDC6B9AE702A034BB3A2C6C230E58EE5759DC84AD0B960B111153F6D619E850E36833A26689B4718719EFF3A407B77B0BAD24A17E29B6A29E9125B4CF0DFFEB8D0B03D533ADA43D1F20CFFE0A067E0F6FFF28510148DD72AE33D8B72227523497B84082B682A480FA3B2FE42AAFF49883DAA4DC6826C9593D38002D73FA7AA91B41E828CC34FF12ECC1452B73709696A440CCDF3E6116DA36CB7A01C9E168C3518304721D2CDBC077F4D4B7E8D1A59F954872862F72AC12CB16E33BED8EC3CFD912E36BBF4DA86E31F5F45BE9294550965C7CBC03518AD7C5637A97F7470EDD6E359E82815230CE03AEE9512939A214D017719E5F6B2487E3B468D50DC8EA41EEE94360E77E0EAA9C27DFE2C28D63B7699406E2E6620FE23F96584EEA04034270A2A44096B70017CC2CB197CE8DA3B1924D8D2E86FB40FF59CCFC78B3A4F543068F08C3406DEF52413F95B2BE2AD5DA1ADBB7D95F2133F61AD5518A1BEA018E3C3C0C154EAE56B0B0F4A8818AE47DC618D138245192D055CE4EF8BD1A75030EABAFD66E45B204BA6B123FF54D78F51B6A7DB9B08BEE93E923F9DE553EC0BE4B8BE222998BC792002005ED66C0218902E7DDF6C6D5043A8A9790E438D5BDE37791CDC0DB6C974638884270D4F379DF845281C5F1F8A20978086A9444779D59423B6CEF8175E0BC2C517FA921EC66BE3F11ECEE078553F610D5B65FD293E37717C0CB323A2760646AD56C77A4B96940CF5AD1154A642043E40788C2D367123399FA6015422F5EFEC851EF558ACD4BC31EF3D3EF912241A586E54B97FAE083EE45FBBBED74BC9E3887795FC2EBC5354ACA358EC509F4AB8B2967488D5E5B77DD44EB72E66694A1F490ADEB2848918531B6FA7216C51CDB507598F1AA0985626482D3546BEF5CA3BB409934D11AECBAD47389F2CBCD85FB4DD1A8A6F4D0C28920671A31FFC14FC00FC51296A6182D5A05B16B33232798F0993C78BCC662932E2F57626D639DD00E39B206C1F8A15A19B5DCA9F8B015611AFA47A10A30527F552A22574E15E3577EAD9C7B89782F82D7082D747B50CEFD38C6F17D6269A696F518EE6EAFE1E1EA96FB4D";
+ char testResult[512] = "7299FE513582D71A3B9EA1E9F45F95FD";
+
+ // Get a MD5 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::MD5)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+#endif
+
+void HashTests::testSHA1()
+{
+ char testData[4096] = "0583243FDEDEBF8C9EA4017808B490A2581A5A06B8C2CCA4F2259B7FABDE4BECA9F80C3EFBFEC436CF5F252568CDF55C7D31002456F6FE711D404F9A274037E8D55EC6C55077E4900EEAF6524C44FBFCC1C5C1C6AF962CE22106610A7C8DE7D725BF924B81EA566B952C8723E0EAFA21EB2C6E6F5528A89FC24C478C0600CB4FD482FAFF8507284C5F1E8AEBA9CDBFB3E71D77B775DD7C09E65049423BBAA70499450AE3B46703A4A44AE281C1F0341EDF0473B079C44E0F9EFB4C3683ED706E480C901A16E77B52030A7E46E31991131AED9C98DCA1850A4BD6F35DBCF5A894A8843EE656EF0DC617D923EB38426855FAA2E77E70CE9A8AC81D0F14259A748F9227F732420CDAE5A1CFEA9B541F0B12ADD5D966EBF66613D7FBAF5FFCAC8D625CFA536DBCA8E54B01B237211656F165A8114CD157E82870BCCE6AE8AF5334105B4E50B0A4E4AE5D0A3CC5CD8FF85F7C4D20D2627694B168CB48DB81B5B78C620C7559B2043C268F5D7351256D41FE892ED8EF6F7B5DD8E193EDCD268C55C209DCD0E827FCF76D6951CEBD0065826FBF044ED5818FEE4ECB99973FDB6826BF92488652E804C40D07D4CE43FCB31481667EE637721B91FD38331A98A6E8969D5B1D0690CFA0B500D72BF2D42AD6471FE064496C91126EFCC46B8CD093BCBB70D21FDE1937A888CA08DF3068A858280ABEAF71608BC9229E8E5EFF1814C4887E3A26782A110F347560DAB6B07DB8D063E8343A3FCD99B34C3C3F649096339CA7D39DA6F7B2E489A9EE6CE01C923D45C50350AC57247838E323F1B2A284606E45D60938A6F492545C5EBA0C7396702C0F4E77F36AC9ECE7ADD32FA4EEF7B38F9FF3F8BFB4E05F1025AAB52FB1B4777A4FC4B881EFA484D04397DE4312B7EE2BCEAD0ABAC0513D9C1819F59996AB5E94D48C098634D9907A4CA41B5A900F7CC299937B089A52C221333BF6B35242CA8D552A9CAA3BB18944D5CCEF69E752FA74A8BA3DD58159BAE375944B26A636457C30C451A58984BD6F028C8CBD3ED893ECD2F1536AFF3A97DB92C0E2FC93B9CC3837FDF56E4E3065D10B15F9A5A8925A5F772E4521CDC885180ACE49D98719BCE6770604C11E6DF090C199A5BBF1D695E1D55E2C9E135E89AB26446F6FED3FBD7DFE58EB75CA61B2D3DA4974908C7183E62FDD79C233387C78EDFF8AAC412EA36AD929808023EF04B8C9B7F980CC3FFD50E7356F51FBDC3DE8551C4F5B283D41E861E5604155E81748BF017268D4FBA8D253CA695300F5FB9A51190B24E2B17653519A3FE500B27DFF90A9FDF8404AFA8FAA1C4F738EB45969846E0A18693C06CA5FE2F2B5F7A33974A9453383E558317468B47DDAEE7A2AB90AA2446155CBF5B6473628C1D6BDA9044D4D96D1E3846AA7A65046C680BB173670FC04E5AC7D8CF41C6F233BD6945C0EA90958E9DBFE67D0EBCD";
+ char testResult[512] = "9A5BD96DC0CD3B0089FBB6BE7D56BEE638431F5A";
+
+ // Get a SHA1 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA1)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::testSHA224()
+{
+ char testData[4096] = "8F300FA699500CA5E1E22B38EC06B2EADCE7738CF6A55CB241577D53ED68BD017517C83AEB9CD3A25536FE999B7CD61D9E2BA85C39A7D27CE2CAAC8FE7C12FA1B2905DB85ABF230A813C1A72D2BD93BE0C5A79842FE35C5EF4B2E94524FB9594E3CCC63FE2A4E21D91C25DED832FE8BC9788697051C2042094585187394BD0AFD64FB627F3CCB350874FD0D454BF0254A72DD99ED211F68DC15B94A5682B73B89BF533746E8EEC5CCE45DF55466D7026A95A062EFD49FA270751A8D427095D38FB757FD4D1395B5DC7D302D9CF28C2E2D09796B9E0FC2D1F56BDE005FCD266B097822C170981DE2DB5E92582A612019823A3A062E228AB99AD6A0E47C1DEAC0078460252D83FA11253A3EFD374B2B392F0E27079F9FCACBB8EE6320C7A06327335AB34B757057E6C7FEC5004C4F675D2C4ACC6B359CC13D6F9FBE7E12EA7F6FF753CA8FB68059DB06D9804CBE08AAA55E0F20EFB7094695C1BF0D8E504EAD0836C0E6BB491E1691FDEB9ADFE0C92CED19A612DBCA01FF5A515E32B4EC06BDA00482DE721B6A85F00CAB264B34C5F3749D35603D0216C5AA426BBFF15637D1AE7805ACA572337232C27BDFC9D17D5D129242FD883E3C33250BA089EA03BD794C03D8DB9F57F87DC0A30E37F063B9C4C43518DC9F94E7BB18718D1DC79474CFAF60CBCD5CAA8AAA9FF573E26BB8B722C522ACF561FF34A0716FB7C1217050AD6E8323889B47D7551BC7554909651A9BAFCF5F0FEFD100D35B2E06D89C46E572E3EB5A07FEA702DF10BBCD2CAF2F2A62A9BC162F6369D0DBD9A6D6368ECDAFF4246DEE682C2B20EF4D7BBCCABBE0CD44CFBB531F2190E55C1A650B4D16DB2DA0453B23C4F056C1F791336A7266742976653B2E9377F500AAEFA1EA5FEE3469F4A85A484F69FBFFC1C163F78872AFB79231D9E5B4F8EFE2A9E8487BC33E4EC462F9E451BFEB306964D1F02873EEABCAB0F06361DD463398717537C7C255E3DEF1E9EC1567A600CFEB63F822A3C24B3524225A40F0CE948B0284AEF1F9BBE7618D18839725087DD6BFEE15653B981D6F57ED6685388F3B510140F437E93B92583609D4B873BBA3641B2DB56AB26D3DC27A85866D8F66C4A33D82932ECE277387E583BB20A689BE12B597C6199799A3A53B970596355A46F7F94B9D5E07B09B8C47355CE19D7D2EC1F1DA8F382F7C90ABABDED1D82C8BD673C008E16102025B8C8AD33832953B9E28A1C01353C513D55F4E38C0FBC1FE7C1FB6B93D10B464F851BFE26426BC09C599708CA1CA3413BC4B147CD69A761E688E3846949AC3F455CCDC0DDB4FDBC91D880B38C73B7AD4C8633598F4570E3BCBA3C5E785686E38D2926187CDF0479DF5B818EBDDFDA757C31DF009ED234B3C0F2BC1ADC700FD715AFEE46AE5CBAD02ED086912BE45BE2D61097F008E45067C4ADC4FDFE29220E6CF0C6F7F8";
+ char testResult[512] = "A4E71A239CED53E936011DF80B516A07DFF13BB5B05BE43C46C05CCD";
+
+ // Get a SHA224 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA224)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::testSHA256()
+{
+ char testData[4096] = "C75FF0C53CB345524BF9800FDF53CE448F3369F9CA08C817F8F07AEF0689274527F0AF1EE7FB5AE99B37456765F39880640BF6C5582111753758DF49A9A13B52379DA0C7AE930B03BC57CD819D2EBA0E38AD33D10876608B99A69D0A73F001065276055C4B659F62F77E7232B021BC085A2472293D2D1875028444902AB29D78C9919EC52B33C9F839B1F839C7FF39B68669C925F53AFC865C93D3694E2FD3F29FF0B7773BB412D0FDB1B506A4D501F840D01AE9BF18D7558109B10A6E55CD8CF9A5279D559810A0B08C84C2C8C294AFEC06C6219EB1647A51488BCDDAACE7C652BB0D3F1DC552E4B42BAFF52FD17239F4C08DDDA1BBA97D8D35D3A3DA32D66858B2D320A62AAA7C3909C3A34DCF9DAA69BEC13B7B3EAAEA8A56E2C6DB2507C43BE8990ADC4A281B8BFC6C76FAED50217F109594902FF7E0EDFF5C018B0FC76CACFF84FB9EA97D6D543EDA732089E82FDE3B9D087320014680E5EA2B21B534125806B650F3268DB7951460A9E32F2EEAAF69300E6F0B7F846ECBC2904E93E8D0423FBDCC3E34C5085A97636EA9961B00880BC381E37C3A6E3115256B1A9E1A915A401A8E507F97A09BF3881E852FEA614DF76D709DE6DC0FE54500E0C42132E9ACFFE4A4A98654190FC6C14FC3E5F42CDCCAE0DE05DEF5F6961D7D13DE15376F35142C5846013B7D4A8A6AB363EC7932415C556B83787C86491820AA29C2FE31E39A3D73D710C490D1AF863C4166C2301ECF6967506DCFF6F97CAE63245634153072FE27E9C4B5F90B3C42E4BDB4FB0E85A548CDE2D3B480ABFB1ED6F054017B120E41529909AC055A9F5A29E25D0E5D1A8E8550B9C85C300BBAAE030B22BB646B1FD3A90FA1C242A26071423B3E239EF65BE8B347663B6BF63436AFFD311D10FD24C8E8D05CA99A808C41E6C9C7B283FE5FE9E311642349D2799B6D0CACD5826CC6CC5DDA22FB8BBDD6C66BB722697E4558A75B6D24FDD55631C17FCB591CA3CBA180CEC241B0555A91DF4D47A648A7D901B02C1AB557C4E1CF33E277AFE008D586857203FD6CE695C8EDD446F74056B173D6A0B07A2A58B39366B58BB76AF96DF9C37A5A5E1F8419163CEAA304D451DC38B8F142C422FB475869667D55D88F7C2624FC0B29A958BB4A44C6B0439542AAB02319D46B7E482149DC9A7C7BEBE651C7E8404140601CDB3742F58B6EEDA137FA083BA9D297F91B41B34C3535230841F18B672ED0FD817B7E4E3CD1FC018CDA63C21C3C3ED68228DF85B8C26572D1B14EF10D5D0BAF6F3ED4B9A8C3DFEB4EDEA00CE2DB5903D510432BCBA791C1BBDD2770F2616AF855941E1BD710CEE4F17C4C7A9E283B12DE901A88D634E4ADE69ED529328D64F8069033A6B4DA5D8E0E1C0150DB862AAD54F2827B41CE1F21E3F890033FD46E438615DDC527D6D1260BDB79478D6A0BE2B58174648A2387E3AE";
+ char testResult[512] = "3902802C215A5271439FE3E81AC7F21DA55545F71193A8DA8BEB0EAC8046A43B";
+
+ // Get a SHA256 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA256)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::testSHA384()
+{
+ char testData[4096] = "11FCD8770F582C2D9C860D1EB4FDBFE40C551C6F3AF41A2540A39BA3A121BFEF995F1727A8703C29D0A44EB85B339F27955E1C679796A72980BB1D1BEF4D51A73174A983D36CDAD56BC1EEBA5DDD642094996531EEC94DE2FB6E0ED4F23BCB2F1D0B25505EB16306473DA17F809BD994FD9A737D29819BCCF94CA225D2EBB9D89DDA6E03E80A9DE87E44B72EFD397F9F344122B6591CED9BFDE8C0C42D8C17223A93F33B7D569291F91B619297F233C1454A168AAE126E89B0ED32B0B69AB095A1BB24BB7F1AAF8EE0BDBB43025EF3339F96C9EA352E78BA0661DE896E8F4DFAA7EF623F2B5305AD338448C5FCBDD6CC1F1222ED1D8F4C634B82591F8906DA8DDA9A0FFB0F1499B5BD08239F7EB3A02ACEC60FB76754D0AC5077C3B733D346F0BDE654CD612F60E2284115297A1557679901A911C2AC7323DA2FF3CD57895D7D181AD43AB7068609CE046B96B445EA08CDF50C40DFAFBA9F7082707A813B9C8E4E9D7F0230D5AFE40174693512DE96E3FAB1C8F6548880823645A0AD811694B293F788D0D523EBD81851594733EF45FC763B956044E29B29C195BDB317FBF97F41C601A2873C25557C3149F648424380FE79E4DC407A9CECD8F14B843C642FD9921F12786C8A1C6F8514C99672038693C5CF1FBE91F903E4ABC9E55B967B2F72FDF1A2EC09C14C94C001BAC47A0C36E9E6F34431381069CFD64D85F11285391A4DC7419B2EE8062F344538413E757EC258192B90F2CCC1186AB9A4ED5CE1290644CDEDAF03A4BF3E94B9F9D132ED159CE03586C5A69EF0A471146378BCCE799A3CD8D627B688BB28C9288F44D1218BC34A05BEAA398371ADC60CA8A2557AB69BE7B737F84BFFA93A1E1115F498600F52144E0D61055A2FC0CD45E20962CB2FF475896D733C74C2E95986389ED74B1497A35E73FEE0F36270CC65D76C1FE27A35E8F1FA0C5CA7F2C6003E21BD6677502CE268EB55B16DA863FA291AA111F338F10592AF86DFC297718365C04839748195E20A64BF42020846A46C94F1728549B8310A7FBCBA2C1441B033639CE52B6DBDA69F6ACC57F2DE6BAC57755734AFE4B77869C4D9B0DC56B115476A86A82F816CB148CDFD2B1DCCBEFCD4559B59AA88C6429F4A9EBB43B641144752A5E6F8BE1B739AA69FEBCB8D7439E5D917CA759982146E627FF81E80CEBC37BE0CF2A6C12A3E84A389FFD25013C491AE90A395D4DBCA81340E86848217AC426603CCAC981B5ED701CE9AB2851DC5F2ED72484FE99767C0FDB6F122B0C67926A637B57EC4F047804BC3A9BD55CBD78B83154BC27B6F8A66085EF02A206F329F3B1531ED657C75E29DF4276070AE5054F484A12990A9DD13C112FB6D3D57AE42E6A048870FDAABA48F73E03344C0E13832BAFCA2AF81AF19E5C28983F7BAAA5135803E78FBDDF7FB53C9B9B709274F05C774C77F0B84";
+ char testResult[512] = "753659D55E4198325A3FED0A35761EC45038E8963B7525BF00D5A6A5D904DD9FA3FC80AB020185E08B14992ECC36A744";
+
+ // Get a SHA384 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA384)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::testSHA512()
+{
+ char testData[4096] = "B9D5BD978E1B4A0268331AE4F0C4494EBA71125ED75B9B4244407271A29D93BF5BA0D6641EBF7A210A0905B5EBE675F7B900B89542D0DA6A3952DF9DC5430ECE31F4A5834CCF132724963A088DE43966DC9F46011F2AD458E8FCDBA18F6D183235687A6145401E9FA2EDF60F47F3835D953B5856B1F8308457D9CEC29246DC51F5B42BD5DE38BD89945667579C05756D1C47BB58C2C3D049C58C014C1F6D962BF5EBA1D273F5A7FD6D9291E293CD30B8D8B489E79E54A7A11953EAF4FB6AC7F99910ECE05B511E098B6AD33A599F5A8FA43692FDD9F2A26F316427A2ED1F231E328864CDF9BA2879E0A711F48038E653520C74B7EEA8858F17AC332B87EF4C70A838263C8B17B373161A5A15293D1A7991F0EEAAE0BB69C95DEC22A1CD6808122489703770B5E276735F9D149067A7F3E6A7D10A790253C81778BB79C06D1F98A2CA9C2E8C4BAC0A96F0F9736B85E7BB4F090C5BEB25F087AC037517A9599D94E072D03D9C48665DD17649E001E45966AB8F2C7D24E38AE4F0519F056B034E0ED2CA133F108105BE4823758543791225144AB0B9609F0F861B69EEA8707D6DB9046910F28C6F8E1D47F59DFE9B59F81242FCBE5A71669B90F7B4050E517CF6D3F2FB8759FB7300F12C786D36183FA64692F379D030D0EA90859D9D8E00F27500B41FD716E325E695E3D8EBB40A4E32AFA75F6F21013C8A3261E9C18291DC99142FFF91EAB6C2B55FF5DE03B1DCC88C79635B96F13B66CE6E26A1D5F6154F3C6E5F22AF4B0334FD4521AE57B6B13E2D3B777AF66742635740ED4FF5FC752B908A079A6BBE8499344096549E6FC6FEDBE57AAF2992E7CBB19931F43360415C39D65D2A92775C78DE97C712022460E48651EBDDB9E0527C7EE59F6C817499100C11E884633DC66EF85B176D7A529894CA8F364F559D97DC7CF1769813FB36F8F738E77354C14A560CB98DF92BB5BB16A5A3EDFB75CB78A718C070BE5D37A6F742F88B51BC633FA9E309311BCA908F4D5EE381FB593B7A53E4CE3A529160A2965D0C4CEDC6548D036A1A4FE4576DA9D35E0CDDE9567E792D5C77EFAC17E531F402E0BE99957A7D378E90C009F3231FEE6E3898B5D2C4291EAD396CA748AB0A39469B921BDC5F8066AB7F0D28EE0C502EBC95C2A39DB4241886736F17DE1F33BD384EFDEA951BF775A0D41A499E85D0488016D7A281A9F7C715EBB7CD6AFBA59C1A93A5AEA66D71C3058C5A293141EE4D2C3E65853EFBEFC55912F5C08B9990A66C313F3199C0769CDCA711E877766ECA773EF2FDBC0656B8427CA6442062D911B13F1C2E92D3F0C608B1D8F12914953720021D5648364F953F93CC49946E44FBAF154A2FE3A8055922F784FF9B56D5FAC35B65266A248794101C12750DB8C107D048E551E52EB3952CFA26345B4E21652F5F3B8F85DE04AF9731B75C79DDBD6FE1A5";
+ char testResult[512] = "E1483A8525CE39705D14D60D8B19BD89087AED5FE6D8913AF8FC3F6F4EA2C1BB5957E205294B1EFAF20AE5EE39A9522F38B4514C3C15ED70BCBBD5821E385F95";
+
+ // Get a SHA512 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA512)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/HashTests.h b/SoftHSMv2/src/lib/crypto/test/HashTests.h
new file mode 100644
index 0000000..dd6566d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/HashTests.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ HashTests.h
+
+ Contains test cases to test the hash implementations
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_HASHTESTS_H
+#define _SOFTHSM_V2_HASHTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "HashAlgorithm.h"
+#include "RNG.h"
+
+class HashTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(HashTests);
+#ifndef WITH_FIPS
+ CPPUNIT_TEST(testMD5);
+#endif
+ CPPUNIT_TEST(testSHA1);
+ CPPUNIT_TEST(testSHA224);
+ CPPUNIT_TEST(testSHA256);
+ CPPUNIT_TEST(testSHA384);
+ CPPUNIT_TEST(testSHA512);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+#ifndef WITH_FIPS
+ void testMD5();
+#endif
+ void testSHA1();
+ void testSHA224();
+ void testSHA256();
+ void testSHA384();
+ void testSHA512();
+
+ void setUp();
+ void tearDown();
+
+private:
+ HashAlgorithm* hash;
+
+ RNG* rng;
+};
+
+#endif // !_SOFTHSM_V2_HASHTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/MacTests.cpp b/SoftHSMv2/src/lib/crypto/test/MacTests.cpp
new file mode 100644
index 0000000..8a3db1e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/MacTests.cpp
@@ -0,0 +1,687 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ MacTests.cpp
+
+ Contains test cases to test the MAC implementations
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "MacTests.h"
+#include "CryptoFactory.h"
+#include <stdio.h>
+#include "MacAlgorithm.h"
+#include "RNG.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(MacTests);
+
+void MacTests::setUp()
+{
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::tearDown()
+{
+ if (mac != NULL)
+ {
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+ }
+
+ fflush(stdout);
+}
+
+#ifndef WITH_FIPS
+void MacTests::testHMACMD5()
+{
+ char testData[4096] = "B64CCFF0DC038F4B4B6C77677B1E89774028CFB6F94EE920ABFABC8C389F7DE287D558664FD05836E854458940A486A367C9B771A7938BE7DFFF2C695BB99CB96F946707FB405A0FA94116FC4002FAD47F813C4DAF6F39B579A2C1E607AF0F80E55FC6742ABB46CF25EFBAEF820DACAE925532E0F2AAAD64D23D0E5682DC38FA47F230EAA299C4D87EB76D45D4B4A08BB47AC873A428708F9D236CF9B11831BC713DB5C8F58A4A4DD228B7A370154CCDB92420B01D0B4141B2CBF05E51D364F7A4D7EE20F1299A697AEAE7341EB6C2F5C458D8AA9A33CE6B2C87B42A9C8EABB3A3311E3828935B8743604895A37D0E9717266872B51CBAB50E9399A0E54457F88DB022CD1859D704FE07C2B530BE14A11072133A9D3A8CD94FCA2B22A320EA08D0292DEADAC4BF705B2CDF71CDC13EC72918F2BD8697BA42AA0AAD62E2D549AC639095EFD2EF606414207CD3770A14FA14AAD7EED197A1A61EBF1FCA89CFE2B69E709C98F4299CF6E1DCF34A98F3C89C6357B5DCDCB335C98EA8DBBA64700EFF9B79CCB875FA49C0C8FA8AA98D6B7B83C3818C4078A8433EEEC71423D9B476029C190ECF1552CF59E1BB2ACDB08663FA792D806E5FF5A6D3E4E09C3F6276663A09D5730A9AAB456D4863F2EDEFEF156A7809AA16D3202AA03C64359BAC628EA1D9ABE2D99999C2891ED49C6081DEA6907C93C5873B4D7880DE271D6016075AFF330FDF221790258A99564F1B51B979DE7997F5FD6676F679B4B14222753547C06960ADCC287EDC29E627FB88BD0E73EBC4E631A58DCA425FADFFEE9DBA177EC182CABA803EEE16636599A88C39A828A5FB206F6DDFD6023F560A421FF3D93B6C4A2A27B78283280C2FD5D249C35270EAE8F8947FA07189BB3A03184C1D8DDB12038184C467EE7DA6CD62F1775F316BE3C2FAB947D49DA19B480E8E4CB4C7818D7769351107386311E5EE411DAC5136869C147DA8E782FA60ED69B13C2DE18CF11FD75CE5F8F16993A026FC3441EE3B23DD6002B8F015E5CC336B5559A427864338C098F4857AA40399916614E061BB176AE4457CA72625A37F08F179A14C39B065CF3283E9425355B6504784C0F4FC1D7932F5C14B43A9CE3604935DE695CDB60B1ED58BD71AB540EEDDF9337B0743D8E624E1A932A69FB1FCA21CFE7F6D2FFDA78F2B8D5BCE01C59BC0A3981BB3BBECF345F43ACD571432B742F80491B490FD71F947480FF9D215EC21237F5AF28C31608DA7A6230CAD24EA799506C8C0B1298E9FD09DA496C6B63710920CC0DC14C00944A7D9B9B751D741A828AB35A5926D3653D45531A4D233DE198439D1946633FF6B91DF0744073CC6E3EC3B177414D8ED2AF30515D8688914667F507667776634A2A11BB68F65B363BD56E8CCF957EB4BB0147862D4C17268AFCE5685C8346E1917B8E8618D3888355CE401AAC5D2DF";
+ char testResult[512] = "1026862877813E17E4371095271E1B56";
+
+ // Get a HMAC-MD5 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_MD5)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-MD5_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate the MAC in a multiple part operation
+ shsmMac.wipe();
+
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+#endif
+
+void MacTests::testHMACSHA1()
+{
+ char testData[4096] = "EA9E200DE69522895F516F1380536406D205D72B31ACB902CC582B12696579826B5AF47892C4831D8AEBBAE039D87F82096364782B49E2E896AB8077E773AB61E05A8223BF17CBF37AB1BDDA70C9B10D9943AF4109571ECFB029156889249B309EC45A34E2D701F1F4093610A7064B69E7FAE5FB39E39EEF3CAA9D64E50DA8822DF4C8DFA064B165ECA4C9CD2A6AF1A251A1F5D4004123B67A7CC3FAB7462AD43535018479BDFD24A2C4A1C4271F907E40E2057A6271BB2BC9740F753CA3692E7ACACE547E64B9FAE79A96DF3DDFCDA7FDCCC7612E41B0B9BBFA3BDE2102F322E8EC42DA2679531782920FD2E7385F6AC887D578B9D844F6A7288EDF613F3663EB538DBFF14EA29AC8D2F58C703303CD370F55BAF02532A0BCB2F80673F6D84B04A5C3EF9E05B640B4CFFD903272089B9960B54197CB5D10C23BAFEA72EFF79C65E0EABEC628EEB5850AC4A23DC80E857EBA5EC5EDB9DD0A5F391B7F8BD354EC976881C157BD5735AD894F020164A9DF214150C5788BC1CF73C15437DBF21D791C75074DF4B51B5C0ABDC79063AB7B7CEDEDC6412F9FB1F6CA171BE6814E033F32CF1F08236A3DD657DB96CCF7A35434C4D0ACFCA81546B4138A6EF6987A874111946010F78074E69BA83E3F395D1C239A122B259F48140E4B80157738A5D443E1762C55EBB67791D5297B3E900B0B53CA7433FB61D2D03C3B34772C5DF77711437003C6DFF4B03DC0B713491F526F9AE3260F903EF9A1BED641E1B262103D395ACAC3FE6F6F1436F0CB3A13AC69C60101EC394DAFFCAD8EED23893C4BC30485FC68854447A9930C0F4FB9AC5B72EF6512278F09F5A024C7CF5C5617461751CE193E54051AE93DF136725642E1DB98842BAA8B8F6231181F0BAA8393FC2EDB7CF0832BA1FDB76A46C8059732B7492711AD1A12BA584D49885E263789E27664B3893EF2DE5C010C093DE1A735D806E4D48C36A0995EADF011FB50D0CA97AFF26B4698524B9F75386897940434A0A38EAF513845BF0F024014001180C651F76B9E0ECA6499F177A1079395C1785B856D5762550EAD2B47B15AF0A6BFBB1B597E72B9E5E6F61769C27AFC29E4D8A523C89D1D2E5E59B57DE89BE04BDC1DCDA0476A157BCB4DA2F7AC0CAF9351772652E2E5B6261501BDF42C23EA9726CB6C258EE9511684CFEECA1C0598D372808002E250EDD4019F85630FD499C35016B8A99C6BF78E69053B4AE7BE6B84009B505594603B363037212DAFCC669F7482995C74A7CC225245DC2E7D4CACC8A59F67513E1D788F0218DA902F440CD2FEB6C2A90A653B0C2DBE45CC67B47863C1090F3F41AFEA9C53CE5C61A7E6B7212EE3BBE67ED91EB1BA006A931055512046779935F84D7CA306C7F9F3894F91F51EFF6005F5A8BD9DD8828BCEA1C4CC6E5F22CE7F14C0A942243C1205FD7697F09C333AE0B263";
+ char testResult[512] = "C2FFE4BF83A6FE299CA4A187157F2442EC1527CE";
+
+ // Get a HMAC-SHA1 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA1)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA1_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now verify the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now recreate the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate a wrong MAC
+ b[5] ^= 0x28;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac != shsmMac);
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testHMACSHA224()
+{
+ char testData[4096] = "83E369A9F34D645B7E1F2F7BB676A4DFD36C411D5472A9AC6F3945EF5C9A561BB040C38F2F321C582882820C7F44D48CDC5BB84F41818F4AEB226F63078CE131481D26F26C61EE52BD1BFB60EDEDE1E03A8656E87D5662EE0C0AE085E56E488325512467DAC43E99484A16FA419D6704922C1ADE06F7D1188DBEC88384CDBFDCD2E74787AE247A8027EF60383B3B0A7D0D3ADA95BB3AA5F0821AF050A9709C75673F3926CF9AE029158D684F470DE3EE6B00BBC90F85CD6E634E86B67E4D8EB4251B472B02D167790C6E6C38BA9FE39880544EA66EB4C0BFF8AFEB9AFC40ADC24DF191744482F70793CB4A802CF1AB58562CC26D1CAA2E80375BA45507C3E9F7D99223E0E7FE93CAC58B7B0C69231162D2D7DA75EEFD59452642CDC5AA4A118B6D4AD00E8368A44988201C6286CAA8612BCFFF714855DE1E053AFD2EEED9737459540E45AEAB26999C0951228716AF02F0D35264E3411B03D222F331A4695D6DF4E9EE35D5B1015FF0BE46081D7CEC9137824217A711F015639BE76223845F1C2A25A10D29B637C5124CF50AB0CAA1E33D75843D00EAE69C3A189D463377731C3197BF44523936C4F84F143759E3D58891F7B3B51C858EE29BC1DF214AF09C93148172E842A7FC0078D4E106324AAF8862B845F290FE831037B2EFEF2528DF070DD7B1ACD67762CF1071B96FB95C5AA14F7AE13103AF45A1CF3C42C5D53CB5B954F97BA223E70E0098E224BEF8F5430D027B510DFBBC35EE5F9170E4A43BDDFCBAE8B82240DB870B6C7C7E21E21234EFA62F1582A9D150CCE1B8822BD77ED8288B20883AAEEB5BDF9D0EBB8D3FF47DD51B99E9BDB8B8A87D0536CC25D4939ECB13F7B4F7DF5F0BE8231CF3F53CE52D16A29825739B26BA4082975583967180F787ECF98AD956A9CE53759E20960752938C142DF80E57DDCA236A1F596031942016442002683865EDB210073797547D83CE77D3D6C39E2B9034E685BD28D365992E821BECAFC6DF2B60EAE9777FEE7879B176CC602501BA0B0BCB434DFA5517F8D6172647364F235B3C9BA0B1B90FE0FD67CF6650C2D8D2BC08D127DF0AB887F69CDD81D03B4CC7F44A4362C90BB38556D081E51EABD9CA3AA6C877C42FD1B001C030D0B281590696B5BB9C6A78CBE356F7AC72F525300FD13E24755294712DDF48D1AD19F844120306DC99D8CC18516A23BD022CF9DC9CACC168ADDE1C15337F15B3FBEDE4BFA498F2F963E14B7E66CD737A5485227BA1BAA7668D97C58DCE40EE7A843A5E6EB591FF91D6A6292C8A3E95A0B23C1F0B8815BE526EE7C49B5153264BC1207013EA85E9DA37F19BD50DDC9F0A5B9AB4FCFFAD2840B5A8856882E8DF95362DCA13C15328137A2A8318884FCF4D05236CEE9985DB1BA873A9AF5B33E317FA2C0CB94E7C18E46744A374C19D8C9B2788FE50C9E4D237D290555E1077";
+ char testResult[512] = "4B089658FF932CA07BF7C42E6EC46BFF560BCAF295826D9D3C0BAE1C";
+
+ // Get a HMAC-SHA224 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA224)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA224_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now don't verify a MAC with different input
+ b[600] ^= 0xff;
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(!mac->verifyFinal(osslMac));
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testHMACSHA256()
+{
+ char testData[4096] = "FF7E669D7764FABF6E3550E192E660DF1EE237B49F9473D757DEFA1400534F57C81E8B0E99458F74E6F57A5BB71A50D1EF61EDB3B3FB4BCA57896DFBA50C6C55B04D4C8C804DB8EB2A273E25F49AE2742D2AE430BE9A3A07715AF6816E818B63BB1FF8C876A921CF931F693E624CDAD4B54F3ABBEE4A09BF39E0FE3A313B20CD3A36B0EBD677D9D4D7C576B5EA244CF0436110D9D66110C95BE187D6EDA1E81A4456231BE32A1B5F4CDC02B2DA679322AEBAE0B795763888F07F0222ADBF824F31AEC7B80625DC36DA1F0C3DD20C6E8F79A7FA2D286119894E611EE550364428723E9C33A573F18D02F9DC90ED215EF08C95DB1CED68DA864732BC9A56B8B191815BCC12075641E3E87F46EFD3726BC1D6F47AF7BC573C554279C041C7FD5E924093241855507EE2A837E2CE62E7A9898712EDF593217B6425B3EB855D53D31F38E5A0736E34844AFCAD58A15B06D357697DC921C2FCA77091BFC207B0B4F1FA94F923B05817211462104287B43CA72986D9E6E393C9A075C267B2C1706CAD136E9F549A83E58315DE8D0B67852006EFE8B6E0773519FE6DB316EA596E1998B79C19152AADDDF8E025E7EDCB16B5CCBA2C9F990605A6969D3C667D6EDA1DA5AFF476661349712CD73F707BB0FD6F8BF0C13A90DE9C1C5CE9FB696C22849C1205C8435C818E2EE03F2235B502E0C24068B8687AF9ED065910535072DABB83F651FC60E005BEF909F6EE308B37E43DA01366C062168007D733D5EA4A610D1307BA087E8F883864140BBB02E523997A0D83E9BF289B8EC9F83F57FF553485409B0D82E77F32BD2D06A130103B9F3915730EE8BC3FB099B74AE8B32C478A83D0BAD2281C279D6B802F42A80E179F4ABB69AD485BBAE348C6F774285870F53699500CEC045B9521CF22826FAFFBC4EABE9D856B28DDBC6D2A0F318AE9475E82DE2CA6704B743397EFE45F825019B58D9E671181512D780B1BA34D059BFBF8B9B232E337335C1045682635CEF8D3CB1C744D3A7791F5DB323EF8DE768C63931266EAB0DFACAB0F99BC9C5DA234FE48ECDB23A5FDA2E92EC10AF7476B07C4BB85BDD0600B49F41585F9E0DB2B276BBE0FA7C5792B65012B6564561E4814E8D1EE706935A45F969C9AA110A630E354C7243E21436A180046605FE5D31008045A5C4AB4FF5C23585D77D6C839875CC2E960436A3D90F9664D5522EAB08867B95F9641DF0C81D59DCA8ECE8709A3F521532041BDCF7A7535F940BD3569FD2145A1B34E955E04F66E0CA809BA3FA6A347FD0CB69DADBA93DC03CDF547A96CD3159ACA61EFE20F9A566316BB9C746EB851CE51F04823667CDA0D898253BB10C1C5220B2C30461A49C5FF0DEC38264786C6125720B3768629ADABCF694E01795F618FBD0ADE5C91CB5A981BBA581A9664F51DF758D7300E081E57CE20C8A7210BC3558AD240B7";
+ char testResult[512] = "90A49F8EB80D8ED405EFC8D658FCB9102314598939DCAA090756668056B0228A";
+
+ // Get a HMAC-SHA256 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA256)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA256_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult);
+
+ // Now verify the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Check if bad key is refused
+ osslMac[10] ^= 0x11;
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(!mac->verifyFinal(osslMac));
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testHMACSHA384()
+{
+ char testData[4096] = "7D4C4274CFAFABE3605DE7E35B43F10251A441A6F4B03EE142B9EAE3DEC2E30E1A47FBE779D716427B108CCB2A2C2D7561B879B1C021E00E0498D91859BA3E7851EF3FC25A1BC6EADA8524EAEEDCC0E752AD90DFD0EA2F04B71B8ABF56DA85E4D070C91EC4B7723A02C3B52DAE31EEAF8E397CC3E92FA31E5F3292D8C9F45D459D8D1105E539D3979ADC01EB4E0C90BC33351295628BD0C2E1B4B13764EDD66BE9AD67AA7B4A7780264B0A3DBE099B190D25649B692401E0B758AB2A281B2E1AC9B4F7EE051C1B98BE92463F314A86A7FD40A4683A82457699F514563C70F1231C0B667C7B8CAD5910334CF894A9810D7C7C6DFC1E904D8512813A84911580C2AC56BB005A4FFB512A1290501AE795C832C0BF7DEBCD9B1D84CC0BB5B5F19D02FDBAB01F7B7CA47C99F3CB7D4F0D35622C267EBDADB2D089D0DA73FEA15A25C873C27EF72A84F99EC4E6980695BA6468B34B5AEC0746219468FEE88277739123FB51CEBF264140FFF27B94D6F751F26F0BC27387A2EFD038EEE43013AFC8FE94BE8E272B28ABFE2160BA81416113CBC2A1ADD96DD23F7107F4771CF2016501A8918A9A71C476CEDC10BB355BC144C818FD620301793CB16372A80881C5DFE387619ED651626CF44C8EDA8DA5BA8A6895148EE36037D4ADDBC13C5681935EDC5BD9B35F8E91B84C1F593B3E89614879CAE4DF4413E13655079F3CE21449CCA19E0963C925A75BC294F343016518D2F8FCB13ED38D574232602AD2416E94ED7735680439CE042145552F352156FCA722B31BFAA289C3711F170A845143ADFEF49CA53278358A7FECBD605AE9899192990D728CA37218B65DD9978EC4345100E174F3D04A0C8A5611263DABF7DA0BC6CE50BCD338830688B697FEB71909D1A2E09B62C5C4A8C1069C50C8DD6A432ED2B429F6BBFC304D0F0A35167BBDDCBC7F78959058393BC812820AF4917C56EA9233A1567608534F93857EA783B537CE294B4778E4B5D30D5836AE1F0D25B663A62512D2488E959D7FF000F8A70F31CC4CABB51D6F57A842AEABD707122935690F78F1F8BD7EC8544F1E70B9D6D53C50632F4DF5F0BC75630B427B28BAF2249C72F5864A3CE17627BA4F16F8FF13FA19DDF83736B171C024C95EFBC5D90615C495C2B02685C24C6E64E19C804B1DC138B5BC52A6969C4332F6113ED8C38F03A0107513C611A6FF013D2FC0B00859A6A5DFB8626002EA0126D477B5F9C7B5BEAB61A13AA8841A4C11E9DFB6A7164BBC2D40E940D9D10C56D58FBC76B92EA68425C2FF48BAE0CA2AF6F1CFBFFBBD855688C3960538E2D87088472CD73AB6D0FB86D9411310F5311EFCA3B89949A87D408B86B96C29C89A0180AF8957944E2A385A221081870CECC995FFDDD6994B0856ED0DC6303F7FDE5072F0B3D68BB132B0C5D3113939D614677720186052F4F90DD60A1CFD";
+ char testResult[512] = "AC387A4BB1E4E078C43C69087C206F49F56EC63CE244A429DA56B8EC3CAFBC987090DA7A8F6470874CA6049D20AC5154";
+
+ // Get a HMAC-SHA384 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA384)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA384_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate the MAC in a multiple part operation
+ shsmMac.wipe();
+
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate a different MAC
+ b[100] ^= 0x42;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac != shsmMac);
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testHMACSHA512()
+{
+ char testData[4096] = "A7A3B0B40CBAAB9B58F6946D9D15870B56E6832DECB708949EBF98DC4EC9C0AF477216C542A98A3646B6ABB72D89E6B3F18201CC75E93B37C2E8EADAD6827FBBFFD220642A92CABB587B27590ED204F8B2C926777C3DC9E5273CBB38582C103905C074002DAA2D8D16DD907BEFB4C51B49C464FF22B93269274291D1254889E3F677FBA6929AF472AECC02DECF822EABB2F05311E0BA8600B58075D4E49837F81C9565E37EAC96B9C2F3C08E3D818DD507D0CC8064C8CC7553D5A17204F4B92B74E5A441CF9142ED059DB1ADA76C799B10178FB3E76E4E3CAC6B1AD8648D522DCA6C93200E706D947E15422E1CC47742CCBF8E2C1E50492AFFA49BE22D5E34B0ACA62744626E2EF7014EAB17D8E538324D9A764501428A53593D23E3785831C1262F220883E2DEEFC66584A3AEC1F35998F842C5298A5E28653CF40F21C6E2383086C266E2902272198D45B38308904F5D2F614A6857E027D133C5455E75B16B9DB124755ADF06B16F04872D74D1A90F36709D8263B1190D625849F017930763AC1EA548DEC56BFD46D09F32D6ABAE96A778B39FBF22B1D6B3CA43F8E7ED32DB2254018FB1999ED0C4C3CDE710899CB20AB5E1CA706DA3E4E8E65253782379B49B7DEFE4E26DD498A935057E91B8FFB8B110336A554A6C61C26C2DDEEE8631926F8A706171B309B99E3B24030C17609340EBB82C4129B172B64CE6249FED00F05DCD624969BC1E4A29ED028C9821A812CDC310A974B959B29E30888887D9A8688E92F85E2A1683C5E993BCC584979F0B3F7DBE34295E2D852B6444EC4152A0C40F3113B402027E323231FC2EDD8078D6661F598588F68FB83DE9C2CA1491107E1F7B676BE16AA6C62B2FF86056905CFCE1FA57065B20A87B15BF1EADAC5FD94F5368451CE8CC2D363BC184A6E87D3D088CBCDE259845E4046D314660B1C1D4AFC7CCC37C7B1B8BBC7A54B63FE61FCD082966425AC3795F08BE7AFD6F9C66F2C3C50DD1EB6B8F8FC3C1A6A298A442EB6FC14AA906A7DA7854B53205E0A8F91C8D6CC3C41F4795FA70E14BA876548022733E61972F0351BC4187FFDE18E776BD68C5E947D2F0B19206D34770BA8ED63874639BBCEAA8D59771A02AEE654D20C69ACD8D16C42BAED6BD1AC51134F49C2A1D685B045527D4A86A7656439A2587F48F5AC43C5094DC680ECE19EBDD53B39F3B84F36D363D8CE464A20DE7ED50C6E32D5C7A9C3868D9823DF0E0A5FD824D239F67C41BC5AD3615AB51EA8B1A2C50B6D4C8F196F1278D9747B8C0B941509850052E63467950EBCE7B56D5E5C481D39E3958C51AE1267C075D8E62EC7F15400A5B4B91B15789015FBCCCC8186DC888CC0BC70326F1800FF56B01BC39DD1C2421BE6E142627B24822790DA36AD9CEA0661FAA03074FAA6F9EBC243DDCB249334B13D31DC19C0F03C6923CBFFEC6FAA29255";
+ char testResult[512] = "93E3A4336693965FEEC902F3BDDB064DD63D83EA1E46AA13DA209F8F000C15F366D3F9BE4F8AF189EA96D191D0BDE4CF0FC6C462C214B55ABF78F33BD6DF3DD0";
+
+ // Get a HMAC-SHA512 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA512)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA512_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult);
+
+ // Now verify the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACDES2()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[33] = "4cf15134a2850dd58a3d10ba80570d38";
+ char testData[4][2][256] = {
+ {
+ "",
+ "bd2ebf9a3ba00361"
+ },
+ {
+ "6bc1bee22e409f96",
+ "4ff2ab813c53ce83"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a57",
+ "62dd1b471902bd4e"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51",
+ "31b1e431dabc4eb8"
+ }
+ };
+
+ // Get a CMAC-DES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_DES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(112);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACDES3()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[49] = "8aa83bf8cbda10620bc1bf19fbb6cd58bc313d4a371ca8b5";
+ char testData[4][2][256] = {
+ {
+ "",
+ "b7a688e122ffaf95"
+ },
+ {
+ "6bc1bee22e409f96",
+ "8e8f293136283797"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a57",
+ "743ddbe0ce2dc2ed"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51",
+ "33e6b1092400eae5"
+ }
+ };
+
+ // Get a CMAC-DES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_DES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(168);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACAES128()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[33] = "2b7e151628aed2a6abf7158809cf4f3c";
+ char testData[4][2][256] = {
+ {
+ "",
+ "bb1d6929e95937287fa37d129b756746"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172a",
+ "070a16b46b4d4144f79bdd9dd04a287c"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411",
+ "dfa66747de9ae63030ca32611497c827"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+ "51f0bebf7e3b9d92fc49741779363cfe"
+ }
+ };
+
+ // Get a CMAC-AES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_AES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(128);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACAES192()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[49] = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
+ char testData[4][2][256] = {
+ {
+ "",
+ "d17ddf46adaacde531cac483de7a9367"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172a",
+ "9e99a7bf31e710900662f65e617c5184"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411",
+ "8a1de5be2eb31aad089a82e6ee908b0e"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+ "a1d5df0eed790f794d77589659f39a11"
+ }
+ };
+
+ // Get a CMAC-AES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_AES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(192);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACAES256()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[65] = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
+ char testData[4][2][256] = {
+ {
+ "",
+ "028962f61b7bf89efc6b551f4667d983"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172a",
+ "28a7023f452e8f82bd4bf28d8c37c35c"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411",
+ "aaf3d8f1de5640c232f5b169b9c911e6"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+ "e1992190549f6ed5696a2c056c315410"
+ }
+ };
+
+ // Get a CMAC-AES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_AES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(256);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/MacTests.h b/SoftHSMv2/src/lib/crypto/test/MacTests.h
new file mode 100644
index 0000000..9e6fa99
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/MacTests.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ MacTests.h
+
+ Contains test cases to test the MAC implementations
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_MACTESTS_H
+#define _SOFTHSM_V2_MACTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "MacAlgorithm.h"
+#include "RNG.h"
+
+class MacTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(MacTests);
+#ifndef WITH_FIPS
+ CPPUNIT_TEST(testHMACMD5);
+#endif
+ CPPUNIT_TEST(testHMACSHA1);
+ CPPUNIT_TEST(testHMACSHA224);
+ CPPUNIT_TEST(testHMACSHA256);
+ CPPUNIT_TEST(testHMACSHA384);
+ CPPUNIT_TEST(testHMACSHA512);
+ CPPUNIT_TEST(testCMACDES2);
+ CPPUNIT_TEST(testCMACDES3);
+ CPPUNIT_TEST(testCMACAES128);
+ CPPUNIT_TEST(testCMACAES192);
+ CPPUNIT_TEST(testCMACAES256);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+#ifndef WITH_FIPS
+ void testHMACMD5();
+#endif
+ void testHMACSHA1();
+ void testHMACSHA224();
+ void testHMACSHA256();
+ void testHMACSHA384();
+ void testHMACSHA512();
+ void testCMACDES2();
+ void testCMACDES3();
+ void testCMACAES128();
+ void testCMACAES192();
+ void testCMACAES256();
+
+ void setUp();
+ void tearDown();
+
+private:
+ MacAlgorithm* mac;
+
+ RNG* rng;
+};
+
+#endif // !_SOFTHSM_V2_MACTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/Makefile.am b/SoftHSMv2/src/lib/crypto/test/Makefile.am
new file mode 100644
index 0000000..bf63ae6
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/Makefile.am
@@ -0,0 +1,39 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+AM_CPPFLAGS = -I$(srcdir)/.. \
+ -I$(srcdir)/../.. \
+ -I$(srcdir)/../../common \
+ -I$(srcdir)/../../data_mgr \
+ -I$(srcdir)/../../object_store \
+ -I$(srcdir)/../../pkcs11 \
+ -I$(srcdir)/../../session_mgr \
+ -I$(srcdir)/../../slot_mgr \
+ @CPPUNIT_CFLAGS@ \
+ @CRYPTO_INCLUDES@
+
+check_PROGRAMS = cryptotest
+
+cryptotest_SOURCES = cryptotest.cpp \
+ AESTests.cpp \
+ DESTests.cpp \
+ DHTests.cpp \
+ DSATests.cpp \
+ ECDHTests.cpp \
+ ECDSATests.cpp \
+ GOSTTests.cpp \
+ HashTests.cpp \
+ MacTests.cpp \
+ RNGTests.cpp \
+ RSATests.cpp \
+ chisq.c \
+ ent.c \
+ iso8859.c \
+ randtest.c
+
+cryptotest_LDADD = ../../libsofthsm_convarch.la
+
+cryptotest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install
+
+TESTS = cryptotest
+
+EXTRA_DIST = $(srcdir)/*.h
diff --git a/SoftHSMv2/src/lib/crypto/test/RNGTests.cpp b/SoftHSMv2/src/lib/crypto/test/RNGTests.cpp
new file mode 100644
index 0000000..da793b5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/RNGTests.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RNGTests.cpp
+
+ Contains test cases to test the RNG class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "RNGTests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "ent.h"
+#include <stdio.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(RNGTests);
+
+void RNGTests::setUp()
+{
+ rng = NULL;
+
+ rng = CryptoFactory::i()->getRNG();
+
+ // Check the RNG
+ CPPUNIT_ASSERT(rng != NULL);
+}
+
+void RNGTests::tearDown()
+{
+ fflush(stdout);
+}
+
+void RNGTests::testSimpleComparison()
+{
+ ByteString a,b;
+
+ CPPUNIT_ASSERT(rng->generateRandom(a, 256));
+ CPPUNIT_ASSERT(rng->generateRandom(b, 256));
+ CPPUNIT_ASSERT(a.size() == 256);
+ CPPUNIT_ASSERT(b.size() == 256);
+ CPPUNIT_ASSERT(a != b);
+}
+
+void RNGTests::testEnt()
+{
+ ByteString a;
+ double entropy, chiProbability, arithMean, montePi, serialCorrelation;
+
+ // Generate 10MB of random data
+ CPPUNIT_ASSERT(rng->generateRandom(a, 10*1024*1024));
+
+ // Perform entropy tests
+ doEnt(a.byte_str(), a.size(), &entropy, &chiProbability, &arithMean, &montePi, &serialCorrelation);
+
+ // Check entropy
+ CPPUNIT_ASSERT(entropy >= 7.999);
+ CPPUNIT_ASSERT((arithMean >= 127.4) && (arithMean <= 127.6));
+ CPPUNIT_ASSERT(serialCorrelation <= 0.001);
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/test/RNGTests.h b/SoftHSMv2/src/lib/crypto/test/RNGTests.h
new file mode 100644
index 0000000..1391d81
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/RNGTests.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RNGTests.h
+
+ Contains test cases to test the RNG class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_RNGTESTS_H
+#define _SOFTHSM_V2_RNGTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "RNG.h"
+
+class RNGTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(RNGTests);
+ CPPUNIT_TEST(testSimpleComparison);
+ CPPUNIT_TEST(testEnt);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testSimpleComparison();
+ void testEnt();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // RNG instance
+ RNG* rng;
+};
+
+#endif // !_SOFTHSM_V2_RNGTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/RSATests.cpp b/SoftHSMv2/src/lib/crypto/test/RSATests.cpp
new file mode 100644
index 0000000..6af1e19
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/RSATests.cpp
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSATests.cpp
+
+ Contains test cases to test the RNG class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "RSATests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#include "RSAParameters.h"
+#include "RSAPublicKey.h"
+#include "RSAPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(RSATests);
+
+void RSATests::setUp()
+{
+ rsa = NULL;
+
+ rsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
+
+ // Check the RSA object
+ CPPUNIT_ASSERT(rsa != NULL);
+}
+
+void RSATests::tearDown()
+{
+ if (rsa != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(rsa);
+ }
+
+ fflush(stdout);
+}
+
+void RSATests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ // Public exponents to test
+ std::vector<ByteString> exponents;
+ exponents.push_back("010001");
+ exponents.push_back("03");
+ exponents.push_back("0B");
+ exponents.push_back("11");
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+#ifndef WITH_FIPS
+ keySizes.push_back(1025);
+#endif
+ keySizes.push_back(1280);
+ keySizes.push_back(2048);
+ //keySizes.push_back(4096);
+
+ for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
+ {
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ p.setE(*e);
+ p.setBitLength(*k);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+
+ RSAPublicKey* pub = (RSAPublicKey*) kp->getPublicKey();
+ RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getBitLength() == *k);
+ CPPUNIT_ASSERT(priv->getBitLength() == *k);
+ CPPUNIT_ASSERT(pub->getE() == *e);
+ CPPUNIT_ASSERT(priv->getE() == *e);
+
+ rsa->recycleKeyPair(kp);
+ }
+ }
+}
+
+void RSATests::testSerialisation()
+{
+ // Generate a 1024-bit key-pair for testing
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ p.setE("010001");
+ p.setBitLength(1024);
+
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ // Serialise the parameters
+ ByteString serialisedParams = p.serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dP;
+
+ CPPUNIT_ASSERT(rsa->reconstructParameters(&dP, serialisedParams));
+ CPPUNIT_ASSERT(dP->areOfType(RSAParameters::type));
+
+ RSAParameters* ddP = (RSAParameters*) dP;
+
+ CPPUNIT_ASSERT(p.getE() == ddP->getE());
+ CPPUNIT_ASSERT(p.getBitLength() == ddP->getBitLength());
+ rsa->recycleParameters(dP);
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ CPPUNIT_ASSERT(serialisedKP.size() != 0);
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(rsa->reconstructKeyPair(&dKP, serialisedKP));
+ CPPUNIT_ASSERT(serialisedKP.size() == 0);
+ CPPUNIT_ASSERT(dKP != NULL);
+
+ RSAPublicKey* pub = (RSAPublicKey*) kp->getPublicKey();
+ RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();
+
+ RSAPublicKey* dPub = (RSAPublicKey*) dKP->getPublicKey();
+ RSAPrivateKey* dPriv = (RSAPrivateKey*) dKP->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getN() == dPub->getN());
+ CPPUNIT_ASSERT(pub->getE() == dPub->getE());
+
+ CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
+ CPPUNIT_ASSERT(priv->getQ() == dPriv->getQ());
+ CPPUNIT_ASSERT(priv->getPQ() == dPriv->getPQ());
+ CPPUNIT_ASSERT(priv->getDP1() == dPriv->getDP1());
+ CPPUNIT_ASSERT(priv->getDQ1() == dPriv->getDQ1());
+ CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
+ CPPUNIT_ASSERT(priv->getN() == dPriv->getN());
+ CPPUNIT_ASSERT(priv->getE() == dPriv->getE());
+
+ // Serialise and deserialise the public key
+ ByteString serialisedPub = pub->serialise();
+
+ RSAPublicKey* desPub;
+
+ CPPUNIT_ASSERT(rsa->reconstructPublicKey((PublicKey**) &desPub, serialisedPub));
+ CPPUNIT_ASSERT(serialisedPub.size() == 0);
+ CPPUNIT_ASSERT(desPub != NULL);
+
+ CPPUNIT_ASSERT(pub->getN() == desPub->getN());
+ CPPUNIT_ASSERT(pub->getE() == desPub->getE());
+
+ // Serialise and deserialise the private key
+ ByteString serialisedPriv = priv->serialise();
+
+ RSAPrivateKey* desPriv;
+
+ CPPUNIT_ASSERT(rsa->reconstructPrivateKey((PrivateKey**) &desPriv, serialisedPriv));
+ CPPUNIT_ASSERT(serialisedPriv.size() == 0);
+ CPPUNIT_ASSERT(desPriv != NULL);
+
+ CPPUNIT_ASSERT(priv->getP() == desPriv->getP());
+ CPPUNIT_ASSERT(priv->getQ() == desPriv->getQ());
+ CPPUNIT_ASSERT(priv->getPQ() == desPriv->getPQ());
+ CPPUNIT_ASSERT(priv->getDP1() == desPriv->getDP1());
+ CPPUNIT_ASSERT(priv->getDQ1() == desPriv->getDQ1());
+ CPPUNIT_ASSERT(priv->getD() == desPriv->getD());
+ CPPUNIT_ASSERT(priv->getN() == desPriv->getN());
+ CPPUNIT_ASSERT(priv->getE() == desPriv->getE());
+
+ rsa->recycleKeyPair(kp);
+ rsa->recycleKeyPair(dKP);
+ rsa->recyclePublicKey(desPub);
+ rsa->recyclePrivateKey(desPriv);
+}
+
+void RSATests::testPKCS8()
+{
+ // Generate a 1024-bit key-pair for testing
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ p.setE("010001");
+ p.setBitLength(1024);
+
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ RSAPrivateKey* dPriv = (RSAPrivateKey*) rsa->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+ CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
+ CPPUNIT_ASSERT(priv->getQ() == dPriv->getQ());
+ CPPUNIT_ASSERT(priv->getPQ() == dPriv->getPQ());
+ CPPUNIT_ASSERT(priv->getDP1() == dPriv->getDP1());
+ CPPUNIT_ASSERT(priv->getDQ1() == dPriv->getDQ1());
+ CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
+ CPPUNIT_ASSERT(priv->getN() == dPriv->getN());
+ CPPUNIT_ASSERT(priv->getE() == dPriv->getE());
+
+ rsa->recycleKeyPair(kp);
+ rsa->recyclePrivateKey(dPriv);
+}
+
+void RSATests::testSigningVerifying()
+{
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ // Public exponents to test
+ std::vector<ByteString> exponents;
+ exponents.push_back("010001");
+ exponents.push_back("03");
+ exponents.push_back("0B");
+ exponents.push_back("11");
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+ keySizes.push_back(1280);
+ keySizes.push_back(2048);
+ //keySizes.push_back(4096);
+
+ // Mechanisms to test
+ std::vector<AsymMech::Type> mechanisms;
+#ifndef WITH_FIPS
+ mechanisms.push_back(AsymMech::RSA_MD5_PKCS);
+#endif
+ mechanisms.push_back(AsymMech::RSA_SHA1_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA224_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA256_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA384_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA512_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA1_PKCS_PSS);
+ mechanisms.push_back(AsymMech::RSA_SHA224_PKCS_PSS);
+ mechanisms.push_back(AsymMech::RSA_SHA256_PKCS_PSS);
+ mechanisms.push_back(AsymMech::RSA_SHA384_PKCS_PSS);
+ mechanisms.push_back(AsymMech::RSA_SHA512_PKCS_PSS);
+#ifndef WITH_FIPS
+ mechanisms.push_back(AsymMech::RSA_SSL);
+#endif
+
+ /* Max salt length for SHA512 and 1024-bit RSA is 62 bytes */
+ RSA_PKCS_PSS_PARAMS pssParams[] = {
+ { HashAlgo::SHA1, AsymRSAMGF::MGF1_SHA1, 20 },
+ { HashAlgo::SHA224, AsymRSAMGF::MGF1_SHA224, 0 },
+ { HashAlgo::SHA256, AsymRSAMGF::MGF1_SHA256, 0 },
+ { HashAlgo::SHA384, AsymRSAMGF::MGF1_SHA384, 48 },
+ { HashAlgo::SHA512, AsymRSAMGF::MGF1_SHA512, 62 }
+ };
+
+ for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
+ {
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ p.setE(*e);
+ p.setBitLength(*k);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+
+ // Generate some data to sign
+ ByteString dataToSign;
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));
+
+ // Test mechanisms that perform internal hashing
+ for (std::vector<AsymMech::Type>::iterator m = mechanisms.begin(); m != mechanisms.end(); m++)
+ {
+ ByteString blockSignature, singlePartSignature;
+ void* param = NULL;
+ size_t paramLen = 0;
+ bool isPSS = false;
+
+ switch (*m)
+ {
+ case AsymMech::RSA_SHA1_PKCS_PSS:
+ param = &pssParams[0];
+ paramLen = sizeof(pssParams[0]);
+ isPSS = true;
+ break;
+ case AsymMech::RSA_SHA224_PKCS_PSS:
+ param = &pssParams[1];
+ paramLen = sizeof(pssParams[1]);
+ isPSS = true;
+ break;
+ case AsymMech::RSA_SHA256_PKCS_PSS:
+ param = &pssParams[2];
+ paramLen = sizeof(pssParams[2]);
+ isPSS = true;
+ break;
+ case AsymMech::RSA_SHA384_PKCS_PSS:
+ param = &pssParams[3];
+ paramLen = sizeof(pssParams[3]);
+ isPSS = true;
+ break;
+ case AsymMech::RSA_SHA512_PKCS_PSS:
+ param = &pssParams[4];
+ paramLen = sizeof(pssParams[4]);
+ isPSS = true;
+ break;
+ default:
+ break;
+ }
+
+ // Sign the data in blocks
+ CPPUNIT_ASSERT(rsa->signInit(kp->getPrivateKey(), *m, param, paramLen));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(0, 134)));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(134, 289)));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(134 + 289)));
+ CPPUNIT_ASSERT(rsa->signFinal(blockSignature));
+
+ // Sign the data in one pass
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, singlePartSignature, *m, param, paramLen));
+
+ // If it is not a PSS signature, check if the two signatures match
+ if (!isPSS)
+ {
+ // Check if the two signatures match
+ CPPUNIT_ASSERT(blockSignature == singlePartSignature);
+ }
+
+ // Now perform multi-pass verification
+ CPPUNIT_ASSERT(rsa->verifyInit(kp->getPublicKey(), *m, param, paramLen));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(0, 125)));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(125, 247)));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(125 + 247)));
+ CPPUNIT_ASSERT(rsa->verifyFinal(blockSignature));
+
+ // And single-pass verification
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, singlePartSignature, *m, param, paramLen));
+ }
+
+ // Test mechanisms that do not perform internal hashing
+
+ // Test PKCS #1 signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 35));
+
+ // Sign the data
+ ByteString signature;
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS));
+
+ // Verify the signature
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS));
+
+ // Test raw RSA signing
+ size_t byteSize = *k >> 3;
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, byteSize));
+
+ // Strip the topmost bit
+ dataToSign[0] &= 0x7F;
+
+ // Sign the data
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA));
+
+ // Verify the signature
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA));
+
+#ifdef WITH_RAW_PSS
+ // Test raw (SHA1) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 20));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[0], sizeof(pssParams[0])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[0], sizeof(pssParams[0])));
+
+ // Test raw (SHA224) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 28));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[1], sizeof(pssParams[1])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[1], sizeof(pssParams[1])));
+
+ // Test raw (SHA256) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 32));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[2], sizeof(pssParams[2])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[2], sizeof(pssParams[2])));
+
+ // Test raw (SHA384) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 48));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[3], sizeof(pssParams[3])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[3], sizeof(pssParams[3])));
+
+ // Test raw (SHA512) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 64));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[4], sizeof(pssParams[4])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[4], sizeof(pssParams[4])));
+#endif
+
+ rsa->recycleKeyPair(kp);
+ }
+ }
+}
+
+void RSATests::testSignVerifyKnownVector()
+{
+ // These test vectors were taken from the Crypto++ set of test vectors
+ // Crypto++ can be downloaded from www.cryptopp.com
+
+#ifndef WITH_FIPS
+ RSAPublicKey* pubKey1 = (RSAPublicKey*) rsa->newPublicKey();
+ RSAPublicKey* pubKey2 = (RSAPublicKey*) rsa->newPublicKey();
+#endif
+ RSAPublicKey* pubKey3 = (RSAPublicKey*) rsa->newPublicKey();
+#ifndef WITH_FIPS
+ RSAPrivateKey* privKey1_1 = (RSAPrivateKey*) rsa->newPrivateKey();
+ RSAPrivateKey* privKey1_2 = (RSAPrivateKey*) rsa->newPrivateKey();
+ RSAPrivateKey* privKey2_1 = (RSAPrivateKey*) rsa->newPrivateKey();
+ RSAPrivateKey* privKey2_2 = (RSAPrivateKey*) rsa->newPrivateKey();
+#endif
+ RSAPrivateKey* privKey3 = (RSAPrivateKey*) rsa->newPrivateKey();
+
+#ifndef WITH_FIPS
+ // Reconstruct public and private key #1
+ ByteString n1 = "0A66791DC6988168DE7AB77419BB7FB0C001C62710270075142942E19A8D8C51D053B3E3782A1DE5DC5AF4EBE99468170114A1DFE67CDC9A9AF55D655620BBAB";
+ ByteString e1 = "010001";
+ ByteString d1 = "0123C5B61BA36EDB1D3679904199A89EA80C09B9122E1400C09ADCF7784676D01D23356A7D44D6BD8BD50E94BFC723FA87D8862B75177691C11D757692DF8881";
+ ByteString p1 = "33D48445C859E52340DE704BCDDA065FBB4058D740BD1D67D29E9C146C11CF61";
+ ByteString q1 = "335E8408866B0FD38DC7002D3F972C67389A65D5D8306566D5C4F2A5AA52628B";
+ ByteString dp11 = "045EC90071525325D3D46DB79695E9AFACC4523964360E02B119BAA366316241";
+ ByteString dq11 = "15EB327360C7B60D12E5E2D16BDCD97981D17FBA6B70DB13B20B436E24EADA59";
+ ByteString pq1 = "2CA6366D72781DFA24D34A9A24CBC2AE927A9958AF426563FF63FB11658A461D";
+
+ pubKey1->setN(n1);
+ pubKey1->setE(e1);
+ privKey1_1->setN(n1);
+ privKey1_1->setE(e1);
+ privKey1_1->setD(d1);
+ privKey1_1->setP(p1);
+ privKey1_1->setQ(q1);
+ privKey1_1->setDP1(dp11);
+ privKey1_1->setDQ1(dq11);
+ privKey1_1->setPQ(pq1);
+
+ // The same key but without CRT factors
+ privKey1_2->setN(n1);
+ privKey1_2->setE(e1);
+ privKey1_2->setD(d1);
+
+ // Reconstruct public and private key #2
+ ByteString n2 = "A885B6F851A8079AB8A281DB0297148511EE0D8C07C0D4AE6D6FED461488E0D41E3FF8F281B06A3240B5007A5C2AB4FB6BE8AF88F119DB998368DDDC9710ABED";
+ ByteString e2 = "010001";
+ ByteString d2 = "2B259D2CA3DF851EE891F6F4678BDDFD9A131C95D3305C63D2723B4A5B9C960F5EC8BB7DCDDBEBD8B6A38767D64AD451E9383E0891E4EE7506100481F2B49323";
+ ByteString p2 = "D7103CD676E39824E2BE50B8E6533FE7CB7484348E283802AD2B8D00C80D19DF";
+ ByteString q2 = "C89996DC169CEB3F227958275968804D4BE9FC4012C3219662F1A438C9950BB3";
+ ByteString dp12 = "5D8EA4C8AF83A70634D5920C3DB66D908AC3AF57A597FD75BC9BBB856181C185";
+ ByteString dq12 = "C598E54DAEC8ABC1E907769A6C2BD01653ED0C9960E1EDB7E186FDA922883A99";
+ ByteString pq2 = "7C6F27B5B51B78AD80FB36E700990CF307866F2943124CBD93D97C137794C104";
+
+ pubKey2->setN(n2);
+ pubKey2->setE(e2);
+ privKey2_1->setN(n2);
+ privKey2_1->setE(e2);
+ privKey2_1->setD(d2);
+ privKey2_1->setP(p2);
+ privKey2_1->setQ(q2);
+ privKey2_1->setDP1(dp12);
+ privKey2_1->setDQ1(dq12);
+ privKey2_1->setPQ(pq2);
+
+ // The same key but without CRT factors
+ privKey2_2->setN(n2);
+ privKey2_2->setE(e2);
+ privKey2_2->setD(d2);
+#endif
+
+ ByteString n3 = "A8D68ACD413C5E195D5EF04E1B4FAAF242365CB450196755E92E1215BA59802AAFBADBF2564DD550956ABB54F8B1C917844E5F36195D1088C600E07CADA5C080EDE679F50B3DE32CF4026E514542495C54B1903768791AAE9E36F082CD38E941ADA89BAECADA61AB0DD37AD536BCB0A0946271594836E92AB5517301D45176B5";
+ ByteString e3 = "03";
+ ByteString d3 = "1C23C1CCE034BA598F8FD2B7AF37F1D30B090F7362AEE68E5187ADAE49B9955C729F24A863B7A38D6E3C748E2972F6D940B7BA89043A2D6C2100256A1CF0F56A8CD35FC6EE205244876642F6F9C3820A3D9D2C8921DF7D82AAADCAF2D7334D398931DDBBA553190B3A416099F3AA07FD5B26214645A828419E122CFB857AD73B";
+ ByteString p3 = "C107a2fe924b76e206cb9bc4af2ab7008547c00846bf6d0680b3eac3ebcbd0c7fd7a54c2b9899b08f80cde1d3691eaaa2816b1eb11822d6be7beaf4e30977c49";
+ ByteString q3 = "DFEA984CE4307EAFC0D140C2BB82861E5DBAC4F8567CBC981D70440DD639492079031486315E305EB83E591C4A2E96064966F7C894C3CA351925B5CE82D8EF0D";
+
+ pubKey3->setN(n3);
+ pubKey3->setE(e3);
+ privKey3->setN(n3);
+ privKey3->setE(e3);
+ privKey3->setD(d3);
+ privKey3->setP(p3);
+ privKey3->setQ(q3);
+
+#ifndef WITH_FIPS
+ // Test with key #1
+ const char* testValue1 = "Everyone gets Friday off.";
+
+ ByteString dataToSign1((const unsigned char*) testValue1, strlen(testValue1));
+
+ ByteString expectedSignature1 = "0610761F95FFD1B8F29DA34212947EC2AA0E358866A722F03CC3C41487ADC604A48FF54F5C6BEDB9FB7BD59F82D6E55D8F3174BA361B2214B2D74E8825E04E81";
+ ByteString signature1_1;
+ ByteString signature1_2;
+
+ CPPUNIT_ASSERT(rsa->signInit(privKey1_1, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign1));
+ CPPUNIT_ASSERT(rsa->signFinal(signature1_1));
+
+#ifndef WITH_BOTAN
+ CPPUNIT_ASSERT(rsa->signInit(privKey1_2, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign1));
+ CPPUNIT_ASSERT(rsa->signFinal(signature1_2));
+
+ CPPUNIT_ASSERT(signature1_1 == signature1_2);
+#endif
+ CPPUNIT_ASSERT(signature1_1 == expectedSignature1);
+
+ CPPUNIT_ASSERT(rsa->verifyInit(pubKey1, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign1));
+ CPPUNIT_ASSERT(rsa->verifyFinal(expectedSignature1));
+
+ // Test with key #2
+ const char* testValue2 = "test";
+
+ ByteString dataToSign2((const unsigned char*) testValue2, strlen(testValue2));
+
+ ByteString expectedSignature2 = "A7E00CE4391F914D82158D9B732759808E25A1C6383FE87A5199157650D4296CF612E9FF809E686A0AF328238306E79965F6D0138138829D9A1A22764306F6CE";
+ ByteString signature2_1;
+ ByteString signature2_2;
+
+ CPPUNIT_ASSERT(rsa->signInit(privKey2_1, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign2));
+ CPPUNIT_ASSERT(rsa->signFinal(signature2_1));
+
+#ifndef WITH_BOTAN
+ CPPUNIT_ASSERT(rsa->signInit(privKey2_2, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign2));
+ CPPUNIT_ASSERT(rsa->signFinal(signature2_2));
+
+ CPPUNIT_ASSERT(signature2_1 == signature2_2);
+#endif
+ CPPUNIT_ASSERT(signature2_1 == expectedSignature2);
+
+ CPPUNIT_ASSERT(rsa->verifyInit(pubKey2, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign2));
+ CPPUNIT_ASSERT(rsa->verifyFinal(expectedSignature2));
+#endif
+
+ // Test with key #3
+ ByteString dataToSign3 = "D73829497CDDBE41B705FAAC50E7899FDB5A38BF3A459E536357029E64F8796BA47F4FE96BA5A8B9A4396746E2164F55A25368DDD0B9A5188C7AC3DA2D1F742286C3BDEE697F9D546A25EFCFE53191D743FCC6B47833D993D08804DAECA78FB9076C3C017F53E33A90305AF06220974D46BF19ED3C9B84EDBAE98B45A8771258";
+ ByteString expectedSignature3 = "175015BDA50ABE0FA7D39A8353885CA01BE3A7E7FCC55045744111362EE1914473A48DC537D956294B9E20A1EF661D58537ACDC8DE908FA050630FCC272E6D001045E6FDEED2D10531C8603334C2E8DB39E73E6D9665EE1343F9E4198302D2201B44E8E8D06B3EF49CEE6197582163A8490089CA654C0012FCE1BA6511089750";
+ ByteString signature3;
+
+ CPPUNIT_ASSERT(rsa->signInit(privKey3, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign3));
+ CPPUNIT_ASSERT(rsa->signFinal(signature3));
+
+ CPPUNIT_ASSERT(signature3 == expectedSignature3);
+
+ CPPUNIT_ASSERT(rsa->verifyInit(pubKey3, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign3));
+ CPPUNIT_ASSERT(rsa->verifyFinal(expectedSignature3));
+
+#ifndef WITH_FIPS
+ rsa->recyclePublicKey(pubKey1);
+ rsa->recyclePublicKey(pubKey2);
+#endif
+ rsa->recyclePublicKey(pubKey3);
+#ifndef WITH_FIPS
+ rsa->recyclePrivateKey(privKey1_1);
+ rsa->recyclePrivateKey(privKey1_2);
+ rsa->recyclePrivateKey(privKey2_1);
+ rsa->recyclePrivateKey(privKey2_2);
+#endif
+ rsa->recyclePrivateKey(privKey3);
+}
+
+void RSATests::testEncryptDecrypt()
+{
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ // Public exponents to test
+ std::vector<ByteString> exponents;
+ exponents.push_back("010001");
+ exponents.push_back("03");
+ exponents.push_back("0B");
+ exponents.push_back("11");
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+ keySizes.push_back(1280);
+ keySizes.push_back(2048);
+ //keySizes.push_back(4096);
+
+ // Paddings to test
+ std::vector<AsymMech::Type> paddings;
+ paddings.push_back(AsymMech::RSA_PKCS);
+ paddings.push_back(AsymMech::RSA_PKCS_OAEP);
+ paddings.push_back(AsymMech::RSA);
+
+ for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
+ {
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ p.setE(*e);
+ p.setBitLength(*k);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+
+ for (std::vector<AsymMech::Type>::iterator pad = paddings.begin(); pad != paddings.end(); pad++)
+ {
+ // Generate some test data to encrypt based on the selected padding
+ ByteString testData;
+
+ if (*pad == AsymMech::RSA_PKCS)
+ {
+ CPPUNIT_ASSERT(rng->generateRandom(testData, (*k >> 3) - 12));
+ }
+ else if (*pad == AsymMech::RSA_PKCS_OAEP)
+ {
+ CPPUNIT_ASSERT(rng->generateRandom(testData, (*k >> 3) - 42));
+ }
+ else if (*pad == AsymMech::RSA)
+ {
+ CPPUNIT_ASSERT(rng->generateRandom(testData, *k >> 3));
+ testData[0] &= 0x0F;
+ }
+ else
+ {
+ CPPUNIT_ASSERT(true == false);
+ }
+
+ // Encrypt the data
+ ByteString encryptedData;
+
+ CPPUNIT_ASSERT(rsa->encrypt(kp->getPublicKey(), testData, encryptedData, *pad));
+
+ // The encrypted data length should equal the modulus length
+ CPPUNIT_ASSERT(encryptedData.size() == (*k >> 3));
+ CPPUNIT_ASSERT(encryptedData != testData);
+
+ // Now decrypt the data
+ ByteString decryptedData;
+
+ CPPUNIT_ASSERT(rsa->decrypt(kp->getPrivateKey(), encryptedData, decryptedData, *pad));
+
+ // Check that the data was properly decrypted
+ CPPUNIT_ASSERT(decryptedData == testData);
+ }
+
+ rsa->recycleKeyPair(kp);
+ }
+ }
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/test/RSATests.h b/SoftHSMv2/src/lib/crypto/test/RSATests.h
new file mode 100644
index 0000000..ca5c86d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/RSATests.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSATests.h
+
+ Contains test cases to test the RSA class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_RSATESTS_H
+#define _SOFTHSM_V2_RSATESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class RSATests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(RSATests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testSigningVerifying);
+ CPPUNIT_TEST(testSignVerifyKnownVector);
+ CPPUNIT_TEST(testEncryptDecrypt);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testSigningVerifying();
+ void testSignVerifyKnownVector();
+ void testEncryptDecrypt();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // RSA instance
+ AsymmetricAlgorithm* rsa;
+};
+
+#endif // !_SOFTHSM_V2_RSATESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/chisq.c b/SoftHSMv2/src/lib/crypto/test/chisq.c
new file mode 100644
index 0000000..3fe4f66
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/chisq.c
@@ -0,0 +1,144 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/*
+
+ Compute probability of measured Chi Square value.
+
+ This code was developed by Gary Perlman of the Wang
+ Institute (full citation below) and has been minimally
+ modified for use in this program.
+
+*/
+
+#include <math.h>
+
+/*HEADER
+ Module: z.c
+ Purpose: compute approximations to normal z distribution probabilities
+ Programmer: Gary Perlman
+ Organization: Wang Institute, Tyngsboro, MA 01879
+ Copyright: none
+ Tabstops: 4
+*/
+
+#define Z_MAX 6.0 /* maximum meaningful z value */
+
+/*FUNCTION poz: probability of normal z value */
+/*ALGORITHM
+ Adapted from a polynomial approximation in:
+ Ibbetson D, Algorithm 209
+ Collected Algorithms of the CACM 1963 p. 616
+ Note:
+ This routine has six digit accuracy, so it is only useful for absolute
+ z values < 6. For z values >= to 6.0, poz() returns 0.0.
+*/
+static double /*VAR returns cumulative probability from -oo to z */
+poz(const double z) /*VAR normal z value */
+{
+ double y, x, w;
+
+ if (z == 0.0) {
+ x = 0.0;
+ } else {
+ y = 0.5 * fabs(z);
+ if (y >= (Z_MAX * 0.5)) {
+ x = 1.0;
+ } else if (y < 1.0) {
+ w = y * y;
+ x = ((((((((0.000124818987 * w
+ -0.001075204047) * w +0.005198775019) * w
+ -0.019198292004) * w +0.059054035642) * w
+ -0.151968751364) * w +0.319152932694) * w
+ -0.531923007300) * w +0.797884560593) * y * 2.0;
+ } else {
+ y -= 2.0;
+ x = (((((((((((((-0.000045255659 * y
+ +0.000152529290) * y -0.000019538132) * y
+ -0.000676904986) * y +0.001390604284) * y
+ -0.000794620820) * y -0.002034254874) * y
+ +0.006549791214) * y -0.010557625006) * y
+ +0.011630447319) * y -0.009279453341) * y
+ +0.005353579108) * y -0.002141268741) * y
+ +0.000535310849) * y +0.999936657524;
+ }
+ }
+ return (z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5));
+}
+
+/*
+ Module: chisq.c
+ Purpose: compute approximations to chisquare distribution probabilities
+ Contents: pochisq()
+ Uses: poz() in z.c (Algorithm 209)
+ Programmer: Gary Perlman
+ Organization: Wang Institute, Tyngsboro, MA 01879
+ Copyright: none
+ Tabstops: 4
+*/
+
+#define LOG_SQRT_PI 0.5723649429247000870717135 /* log (sqrt (pi)) */
+#define I_SQRT_PI 0.5641895835477562869480795 /* 1 / sqrt (pi) */
+#define BIGX 20.0 /* max value to represent exp (x) */
+#define ex(x) (((x) < -BIGX) ? 0.0 : exp(x))
+
+/*FUNCTION pochisq: probability of chi sqaure value */
+/*ALGORITHM Compute probability of chi square value.
+ Adapted from:
+ Hill, I. D. and Pike, M. C. Algorithm 299
+ Collected Algorithms for the CACM 1967 p. 243
+ Updated for rounding errors based on remark in
+ ACM TOMS June 1985, page 185
+*/
+
+double pochisq(
+ const double ax, /* obtained chi-square value */
+ const int df /* degrees of freedom */
+ )
+{
+ double x = ax;
+ double a, y, s;
+ double e, c, z;
+ int even; /* true if df is an even number */
+
+ if (x <= 0.0 || df < 1) {
+ return 1.0;
+ }
+
+ a = 0.5 * x;
+ even = (2 * (df / 2)) == df;
+ y = 0.0;
+ if (df > 1) {
+ y = ex(-a);
+ }
+ s = (even ? y : (2.0 * poz(-sqrt(x))));
+ if (df > 2) {
+ x = 0.5 * (df - 1.0);
+ z = (even ? 1.0 : 0.5);
+ if (a > BIGX) {
+ e = (even ? 0.0 : LOG_SQRT_PI);
+ c = log(a);
+ while (z <= x) {
+ e = log(z) + e;
+ s += ex(c * z - a - e);
+ z += 1.0;
+ }
+ return (s);
+ } else {
+ e = (even ? 1.0 : (I_SQRT_PI / sqrt(a)));
+ c = 0.0;
+ while (z <= x) {
+ e = e * (a / z);
+ c = c + e;
+ z += 1.0;
+ }
+ return (c * y + s);
+ }
+ } else {
+ return s;
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/cryptotest.cpp b/SoftHSMv2/src/lib/crypto/test/cryptotest.cpp
new file mode 100644
index 0000000..2fc7b8f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/cryptotest.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ cryptotest.cpp
+
+ The main test executor for tests on the cryptographic functions in SoftHSM v2
+ *****************************************************************************/
+
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/XmlOutputter.h>
+#include <fstream>
+
+#include "config.h"
+#include "MutexFactory.h"
+#include "SecureMemoryRegistry.h"
+
+#if defined(WITH_OPENSSL)
+#include "OSSLCryptoFactory.h"
+#else
+#include "BotanCryptoFactory.h"
+#endif
+
+// Initialise the one-and-only instance
+#ifdef HAVE_CXX11
+
+std::unique_ptr<MutexFactory> MutexFactory::instance(nullptr);
+std::unique_ptr<SecureMemoryRegistry> SecureMemoryRegistry::instance(nullptr);
+#if defined(WITH_OPENSSL)
+std::unique_ptr<OSSLCryptoFactory> OSSLCryptoFactory::instance(nullptr);
+#else
+std::unique_ptr<BotanCryptoFactory> BotanCryptoFactory::instance(nullptr);
+#endif
+
+#else
+
+std::auto_ptr<MutexFactory> MutexFactory::instance(NULL);
+std::auto_ptr<SecureMemoryRegistry> SecureMemoryRegistry::instance(NULL);
+#if defined(WITH_OPENSSL)
+std::auto_ptr<OSSLCryptoFactory> OSSLCryptoFactory::instance(NULL);
+#else
+std::auto_ptr<BotanCryptoFactory> BotanCryptoFactory::instance(NULL);
+#endif
+
+#endif
+
+int main(int /*argc*/, char** /*argv*/)
+{
+ CppUnit::TestResult controller;
+ CppUnit::TestResultCollector result;
+ CppUnit::TextUi::TestRunner runner;
+ controller.addListener(&result);
+ CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry();
+
+ runner.addTest(registry.makeTest());
+ runner.run(controller);
+
+ std::ofstream xmlFileOut("test-results.xml");
+ CppUnit::XmlOutputter xmlOut(&result, xmlFileOut);
+ xmlOut.write();
+
+ CryptoFactory::reset();
+
+ return result.wasSuccessful() ? 0 : 1;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/ent.c b/SoftHSMv2/src/lib/crypto/test/ent.c
new file mode 100644
index 0000000..b255405
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ent.c
@@ -0,0 +1,110 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/*
+ ENT -- Entropy calculation and analysis of putative
+ random sequences.
+
+ Designed and implemented by John "Random" Walker in May 1985.
+
+ Multiple analyses of random sequences added in December 1985.
+
+ Bit stream analysis added in September 1997.
+
+ Terse mode output, getopt() command line processing,
+ optional stdin input, and HTML documentation added in
+ October 1998.
+
+ Documentation for the -t (terse output) option added
+ in July 2006.
+
+ Replaced table look-up for chi square to probability
+ conversion with algorithmic computation in January 2008.
+
+ For additional information and the latest version,
+ see http://www.fourmilab.ch/random/
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#ifdef _WIN32
+#include <fcntl.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "iso8859.h"
+#include "randtest.h"
+
+#define UPDATE "January 28th, 2008"
+
+#define FALSE 0
+#define TRUE 1
+
+#ifdef M_PI
+#define PI M_PI
+#else
+#define PI 3.14159265358979323846
+#endif
+
+extern double pochisq(const double ax, const int df);
+
+/* Main program */
+
+void doEnt
+(
+ unsigned char* data,
+ size_t len,
+ double* pEntropy,
+ double* pChiProbability,
+ double* pArithMean,
+ double* pMontePi,
+ double* pSerialCorrelation
+)
+{
+ size_t s;
+ long ccount[256]; /* Bins to count occurrences of values */
+ double montepi, chip,
+ scc, ent, mean, chisq;
+
+ /* Initialise for calculations */
+
+ rt_init(FALSE);
+
+ /* Scan input file and count character occurrences */
+
+ for (s = 0; s < len; s++)
+ {
+ unsigned char ocb = data[s];
+
+ ccount[ocb]++; /* Update counter for this bin */
+ rt_add(&ocb, 1);
+ }
+
+ /* Complete calculation and return sequence metrics */
+
+ rt_end(&ent, &chisq, &mean, &montepi, &scc);
+
+ /* Calculate probability of observed distribution occurring from
+ the results of the Chi-Square test */
+
+ chip = pochisq(chisq, 255);
+
+ /* Print bin counts if requested */
+
+ /* Return calculated results */
+
+ *pEntropy = ent;
+ *pChiProbability = chip;
+ *pArithMean = mean;
+ *pMontePi = montepi;
+ *pSerialCorrelation = scc;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/ent.h b/SoftHSMv2/src/lib/crypto/test/ent.h
new file mode 100644
index 0000000..5958888
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ent.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ent.h
+
+ Header file to give access to the modified ent.c implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ENT_H
+#define _SOFTHSM_V2_ENT_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void doEnt
+(
+ unsigned char* data,
+ size_t len,
+ double* pEntropy,
+ double* pChiProbability,
+ double* pArithMean,
+ double* pMontePi,
+ double* pSerialCorrelation
+);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // !_SOFTHSM_V2_ENT_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/iso8859.c b/SoftHSMv2/src/lib/crypto/test/iso8859.c
new file mode 100644
index 0000000..bed7244
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/iso8859.c
@@ -0,0 +1,25 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/* ISO 8859/1 Latin-1 alphabetic and upper and lower case bit vector tables. */
+
+/* LINTLIBRARY */
+
+unsigned char isoalpha[32] = {
+ 0,0,0,0,0,0,0,0,127,255,255,224,127,255,255,224,0,0,0,0,0,0,0,0,255,255,
+ 254,255,255,255,254,255
+};
+
+unsigned char isoupper[32] = {
+ 0,0,0,0,0,0,0,0,127,255,255,224,0,0,0,0,0,0,0,0,0,0,0,0,255,255,254,254,
+ 0,0,0,0
+};
+
+unsigned char isolower[32] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,127,255,255,224,0,0,0,0,0,0,0,0,0,0,0,1,255,255,
+ 254,255
+};
diff --git a/SoftHSMv2/src/lib/crypto/test/iso8859.h b/SoftHSMv2/src/lib/crypto/test/iso8859.h
new file mode 100644
index 0000000..7462f15
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/iso8859.h
@@ -0,0 +1,23 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/* ISO 8859/1 Latin-1 "ctype" macro replacements. */
+
+extern unsigned char isoalpha[32], isoupper[32], isolower[32];
+
+#define isISOspace(x) ((isascii(((unsigned char) (x))) && isspace(((unsigned char) (x)))) || ((x) == 0xA0))
+#define isISOalpha(x) ((isoalpha[(((unsigned char) (x))) / 8] & (0x80 >> ((((unsigned char) (x))) % 8))) != 0)
+#define isISOupper(x) ((isoupper[(((unsigned char) (x))) / 8] & (0x80 >> ((((unsigned char) (x))) % 8))) != 0)
+#define isISOlower(x) ((isolower[(((unsigned char) (x))) / 8] & (0x80 >> ((((unsigned char) (x))) % 8))) != 0)
+#define isISOprint(x) ((((x) >= ' ') && ((x) <= '~')) || ((x) >= 0xA0))
+#define toISOupper(x) (isISOlower(x) ? (isascii(((unsigned char) (x))) ? \
+ toupper(x) : (((((unsigned char) (x)) != 0xDF) && \
+ (((unsigned char) (x)) != 0xFF)) ? \
+ (((unsigned char) (x)) - 0x20) : (x))) : (x))
+#define toISOlower(x) (isISOupper(x) ? (isascii(((unsigned char) (x))) ? \
+ tolower(x) : (((unsigned char) (x)) + 0x20)) \
+ : (x))
diff --git a/SoftHSMv2/src/lib/crypto/test/randtest.c b/SoftHSMv2/src/lib/crypto/test/randtest.c
new file mode 100644
index 0000000..5a54737
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/randtest.c
@@ -0,0 +1,190 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/*
+
+ Apply various randomness tests to a stream of bytes
+
+ by John Walker -- September 1996
+ http://www.fourmilab.ch/
+
+*/
+
+#include <math.h>
+
+#define FALSE 0
+#define TRUE 1
+
+#define log2of10 3.32192809488736234787
+
+static int binary = FALSE; /* Treat input as a bitstream */
+
+static long ccount[256], /* Bins to count occurrences of values */
+ totalc = 0; /* Total bytes counted */
+static double prob[256]; /* Probabilities per bin for entropy */
+
+/* RT_LOG2 -- Calculate log to the base 2 */
+
+static double rt_log2(double x)
+{
+ return log2of10 * log10(x);
+}
+
+#define MONTEN 6 /* Bytes used as Monte Carlo
+ co-ordinates. This should be no more
+ bits than the mantissa of your
+ "double" floating point type. */
+
+static int mp, sccfirst;
+static unsigned int monte[MONTEN];
+static long inmont, mcount;
+static double cexp, incirc, montex, montey, montepi,
+ scc, sccun, sccu0, scclast, scct1, scct2, scct3,
+ ent, chisq, datasum;
+
+/* RT_INIT -- Initialise random test counters. */
+
+void rt_init(int binmode)
+{
+ int i;
+
+ binary = binmode; /* Set binary / byte mode */
+
+ /* Initialise for calculations */
+
+ ent = 0.0; /* Clear entropy accumulator */
+ chisq = 0.0; /* Clear Chi-Square */
+ datasum = 0.0; /* Clear sum of bytes for arithmetic mean */
+
+ mp = 0; /* Reset Monte Carlo accumulator pointer */
+ mcount = 0; /* Clear Monte Carlo tries */
+ inmont = 0; /* Clear Monte Carlo inside count */
+ incirc = 65535.0 * 65535.0;/* In-circle distance for Monte Carlo */
+
+ sccfirst = TRUE; /* Mark first time for serial correlation */
+ scct1 = scct2 = scct3 = 0.0; /* Clear serial correlation terms */
+
+ incirc = pow(pow(256.0, (double) (MONTEN / 2)) - 1, 2.0);
+
+ for (i = 0; i < 256; i++) {
+ ccount[i] = 0;
+ }
+ totalc = 0;
+}
+
+/* RT_ADD -- Add one or more bytes to accumulation. */
+
+void rt_add(void *buf, int bufl)
+{
+ unsigned char *bp = (unsigned char *)buf;
+ int oc, c, bean;
+
+ while (bean = 0, (bufl-- > 0)) {
+ oc = *bp++;
+
+ do {
+ if (binary) {
+ c = !!(oc & 0x80);
+ } else {
+ c = oc;
+ }
+ ccount[c]++; /* Update counter for this bin */
+ totalc++;
+
+ /* Update inside / outside circle counts for Monte Carlo
+ computation of PI */
+
+ if (bean == 0) {
+ monte[mp++] = oc; /* Save character for Monte Carlo */
+ if (mp >= MONTEN) { /* Calculate every MONTEN character */
+ int mj;
+
+ mp = 0;
+ mcount++;
+ montex = montey = 0;
+ for (mj = 0; mj < MONTEN / 2; mj++) {
+ montex = (montex * 256.0) + monte[mj];
+ montey = (montey * 256.0) + monte[(MONTEN / 2) + mj];
+ }
+ if ((montex * montex + montey * montey) <= incirc) {
+ inmont++;
+ }
+ }
+ }
+
+ /* Update calculation of serial correlation coefficient */
+
+ sccun = c;
+ if (sccfirst) {
+ sccfirst = FALSE;
+ scclast = 0;
+ sccu0 = sccun;
+ } else {
+ scct1 = scct1 + scclast * sccun;
+ }
+ scct2 = scct2 + sccun;
+ scct3 = scct3 + (sccun * sccun);
+ scclast = sccun;
+ oc <<= 1;
+ } while (binary && (++bean < 8));
+ }
+}
+
+/* RT_END -- Complete calculation and return results. */
+
+void rt_end(double *r_ent, double *r_chisq, double *r_mean,
+ double *r_montepicalc, double *r_scc)
+{
+ int i;
+
+ /* Complete calculation of serial correlation coefficient */
+
+ scct1 = scct1 + scclast * sccu0;
+ scct2 = scct2 * scct2;
+ scc = totalc * scct3 - scct2;
+ if (scc == 0.0) {
+ scc = -100000;
+ } else {
+ scc = (totalc * scct1 - scct2) / scc;
+ }
+
+ /* Scan bins and calculate probability for each bin and
+ Chi-Square distribution. The probability will be reused
+ in the entropy calculation below. While we're at it,
+ we sum of all the data which will be used to compute the
+ mean. */
+
+ cexp = totalc / (binary ? 2.0 : 256.0); /* Expected count per bin */
+ for (i = 0; i < (binary ? 2 : 256); i++) {
+ double a = ccount[i] - cexp;;
+
+ prob[i] = ((double) ccount[i]) / totalc;
+ chisq += (a * a) / cexp;
+ datasum += ((double) i) * ccount[i];
+ }
+
+ /* Calculate entropy */
+
+ for (i = 0; i < (binary ? 2 : 256); i++) {
+ if (prob[i] > 0.0) {
+ ent += prob[i] * rt_log2(1 / prob[i]);
+ }
+ }
+
+ /* Calculate Monte Carlo value for PI from percentage of hits
+ within the circle */
+
+ montepi = 4.0 * (((double) inmont) / mcount);
+
+ /* Return results through arguments */
+
+ *r_ent = ent;
+ *r_chisq = chisq;
+ *r_mean = datasum / totalc;
+ *r_montepicalc = montepi;
+ *r_scc = scc;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/randtest.h b/SoftHSMv2/src/lib/crypto/test/randtest.h
new file mode 100644
index 0000000..53bef35
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/randtest.h
@@ -0,0 +1,13 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/* Random test function prototypes */
+
+extern void rt_init(int binmode);
+extern void rt_add(void *buf, int bufl);
+extern void rt_end(double *r_ent, double *r_chisq, double *r_mean,
+ double *r_montepicalc, double *r_scc);