diff options
-rw-r--r-- | TestVectors/all.txt | 1 | ||||
-rw-r--r-- | TestVectors/seal.txt | 138 | ||||
-rw-r--r-- | arc4.cpp | 2 | ||||
-rw-r--r-- | arc4.h | 2 | ||||
-rw-r--r-- | cryptlib.cpp | 22 | ||||
-rw-r--r-- | cryptlib.h | 3 | ||||
-rw-r--r-- | datatest.cpp | 41 | ||||
-rw-r--r-- | factory.h | 36 | ||||
-rw-r--r-- | modes.cpp | 28 | ||||
-rw-r--r-- | modes.h | 36 | ||||
-rw-r--r-- | panama.h | 2 | ||||
-rw-r--r-- | regtest.cpp | 6 | ||||
-rw-r--r-- | seal.cpp | 2 | ||||
-rw-r--r-- | seal.h | 2 | ||||
-rw-r--r-- | strciphr.h | 22 | ||||
-rw-r--r-- | validat1.cpp | 3 |
16 files changed, 281 insertions, 65 deletions
diff --git a/TestVectors/all.txt b/TestVectors/all.txt index a9749c6b..62d44795 100644 --- a/TestVectors/all.txt +++ b/TestVectors/all.txt @@ -10,4 +10,5 @@ Test: rsa_oaep.txt Test: rsa_pkcs1_1_5.txt Test: rsa_pss.txt Test: rw.txt +Test: seal.txt Test: sha.txt diff --git a/TestVectors/seal.txt b/TestVectors/seal.txt new file mode 100644 index 00000000..a98812ba --- /dev/null +++ b/TestVectors/seal.txt @@ -0,0 +1,138 @@ +AlgorithmType: SymmetricCipher +Name: SEAL-3.0-BE +Source: generated by Crypto++ 5.2 +Comment: verified against partial ciphertext from 1997 SEAL paper by Rogaway and Coppersmith +Key: 67452301efcdab8998badcfe10325476c3d2e1f0 +IV: 013577af +Plaintext: r1024 00000000 +Ciphertext: \ +37a005959b84c49ca4be1e050673530f5fb097fdf6a13fbd6c2cdecd81fdee7c\ +2abdc3e764209aff00a12283ef675085c1634b53289059e6a7ab5ed9480c01eb\ +4c64569a8dce2a23feed0ef58f6f5ac3f74145127dbcaec4bcb6b1a459bdc287\ +58ba0523f721c3e154433dc7353f02ef487b07ad309ef5e44e6cc19026f5fd57\ +07cc32ec12b9c01fe0c58beb2fe73ea79e24093f05911663a76b21beab18cede\ +17275c54d18fcd3e4cf32279347b22f8751119fb56d92f55d511e4ecc1334085\ +e74934455a2daec3f1821c54b4cb809053b8d837de4186600afedf8bd72dd56e\ +223745c19f76edba01e9b5346666d01f677fbd68fa5010fd7db8b06829a90da0\ +e81b84756a70946a6c05e16d225a2e11af586bb1c5b1d21f5349f8e5e3ee41f4\ +232d554954d1bc86064754b86c1dc92d7a9de30086d8eb4a7c86db9c380f13b9\ +52e11c5b89f1be0a6b52c6e7a053da7359c5fd7f50c70232d86aff08c5ff1746\ +d3bd074d79ad6fc657e0cbbe5d02c4fce55d3c31fef4642ed738f751430f2f1c\ +f6e453ef6edeb9540cec52c697d4864201e141e06c3ddf5aaa64a1a984247e96\ +d2cf1e7fb2bc239919369f4a0bf9d111d0d8be64afae86214d5f62e64f25e8f1\ +3e12680ec170ad6234cbbda938df53cc17a12afea1eb4005122a65cb42bedb76\ +edf029db910fc81b81f3dd28341fed4064ce37648548e5852d4aebb7923016f9\ +afcb07ae7bc11800e217a0062f0b53ffa8d471aa78ca6a13b7f5647189106773\ +0a311d6fe4ff57f05f9a58aa742696b6cbb3ec539da0c2aadd6a60d2a33c26d5\ +8a343448ed912aafb98568c6ae1cb1efaeafd81a6e3e7c450f8e2be4c6cc18f9\ +5e8a1c6c59190a2798e912a614c1e7d0f7e74b1baf8e5682f5442f998b24fa86\ +d1e5f673002e2c92db8ebf7abb1c9d267a9763f4bd54f7bbf07c4466dac0bf3f\ +faf5666a43a52f0812e76df5f9d4da8ed1bc6d4ab29b34718facb4bebc11e907\ +fe9b0e3937de7769fc5b0cc52b3e50d57e02b9b4022949aaf3698bc58f696073\ +ec972a425caee9700864d3d166130ee09d51320b9d51bc9b4aa575c789786242\ +0698d9e1f6426fd141a32c9f55c24e5149e274983035ac1c44833b0179aed63e\ +a2b2b61afa54700155e55c7c343412584f7b0fe73d63c5ad88718dde3000ac1d\ +b4050ae2610032e6b389eec48952a1a2ed0016e525ccd9616706caba89ed07d5\ +4f15ecfaabbc91b7c82c5904bc0f83d44888997faa11fe8fa7333cb8c5b16e31\ +52233c80fbc9f71d9ee8fefa50d67a7e45b93d3469ba4078bb1ed5859e7a8e62\ +b26bacf538507fa6bd43e18d67d7aaf27baaa68d233ca392ce33e257d5ddf3fa\ +ef6a951430d686f65ee9afaf6aee0677b41098922b41fba202ef05a27d614612\ +5daebeb147d617c8df42dba0b91dfbf8ab5805ee9877e495881035fbb7342c24\ +e24f3b85c88671184152ab0d395a9a81afab3bf93bea49cb23ee6bd1c9fb84e6\ +4ecd462f60119ceeae7f1d2150bd36fe7ef2782b0fd12b55df119a517103d489\ +0a739b715d3d33e2ae9fe659df4bc0136c0b243538eaa8f9b813043d66ae15c8\ +261c94c0072afc802668b3151ad1c0ab0f034eb3e8f2fce0c9fbc8f68404fb93\ +a1cd11f4eb9a5eeb9117462ea602ae41fbfe0074323e56e15deb04d41f3510cd\ +1df417f759f4c2bee72bab88833e7d3d9837801f16901ee12581588fa7037f74\ +073b2166405d79098098fb196cc4b1733e45796fa7fc977cbd23853e5943b2ad\ +e154856565a455189198f6ba50b9cc6fda0c309a413ccc746bc8261fd6b060f0\ +5cfcc82894125b3f1e0b0c47257fd838cf295aa13102724163a9fc2598fe8572\ +d0bf844518dccc1ee16eb8e4c9935b78fb969b7c3104091079079a7688f1e833\ +0335f63eabfdd3224a506bae4ea3022a8a4959f4fa410ad7111488a39e3c1cd7\ +a28ce83255de2c4477fe62f660af3b7ba049240aa5212e4e9fffd8b66fd51b17\ +0bdf6c7e7214361a7efdceae86878f49716c0859ce2e24979bae82d98025720e\ +06d7904c9646f1b1058b1a7c93ee4fd728c4f19051adf2ca30f4d54cf65be23a\ +7198e5be5765c018bbc1d2344fa8d1aa908cb8f789ea793c6c60d9a7ba9eebcf\ +7aee50a54810cbe3b632144956a157c220e33a232c169cc9ae64d6aa3560a185\ +fc2d94f15b389eebad8d07662c2be6d6349ece8ef88aea27d430ec9512ff1bc0\ +c5560862fa4a833af750d968e9fb545e3879571ec021735761da937e294820c6\ +585ae00e8023f48a4e1f392217df763a09e540ca615188345512179f8889902f\ +38c626ea3a333fc367818b058dbb8d6aa474ff3438b2de2b32822fdb93f77618\ +83b89223e0e616c885fa3414905d098d82a5359f629ed11589974393cfaf4695\ +da7ee36346d088a6ea6ef21ad6245da8de9956fcefc930c4e2759b596e3f98d9\ +2483b2bd82b74269caae2014f796ffcfe5db58759f0cd4e527b16f989d9cbab7\ +f20282ee2e666cc19ad64aa7a36193ff248002c762280a98f3ad2bf07b32f26b\ +eff5a5586d967d844aba69f7297bb1e28075273f39aa6e7c6c7308728da8ad30\ +31a2d20ebe99940732f93d0440b6e3b481774b69eb76179496350983031c2611\ +a27d885d91ac37debc02512edd06e1d10061325c5e04269c0c14942d10f03f83\ +06ef173d645478d79c74990a82df4b13f2754f273227f96988c25bedaf392534\ +69d73d642305f8058ce4713f65a36b822cd98da3fd805c4408d18dde4ee8e794\ +72e38f8683edbbfdce8d085e005407666eefba25d8c3368c6cb656a699b30736\ +31b8024eb6859019feb76bdb5a0d7f17c92a37fe6bcd14630c1a62bdde1e41b5\ +e9ab7306183a16c31554821ad44229ebce2e552f9a09fd1607dec8c92a1e893a\ +b80c331cdc7860093503cedfd44b3403b3501415916303baef0c68d12efa7c54\ +a11af3a7df5d23df98cfba907dafad0a8989c710d4602fc75f663fb16039d94e\ +f860f358bbf05ac9c34865141030513c4cda32e9b777d9fd9e4ebdc1ad0b24f6\ +799f815e29b8e2259f94b0215b94b349938556736d3ed578cdcea9024d71f174\ +376f05b3c203cc56476dd92d07ecf7e283cc181225a2b690eeaf3cffd35bbda9\ +c4ed0456661e2e39f6be537d2446f65cae13a6dea668b04f8f223601629cd3d1\ +1b75180dfea19435bae5e0622c5005371d4198b8dc1e0c40adbbe08d3651d345\ +4d68507f7f0b56d4bf2a328bb68854064699d0a38d7468ef64ddb4139644fabb\ +d21ad79b5f28a5612e445dc5673b2038e3f7dcf17a12ab32da214fb28500ea79\ +00491554da45661a03e2a878d1006d4fba8e22a7e5dded9b02fb8b5e6d166aad\ +43f8ef3eec4a7050a0304d46cc0be3ec97f0bdd137eea7c001bd8519101ff3af\ +76d1d7710c22c5b0a69c10df3493283254f5afa2ce4b3959d3be512e6ddb78da\ +30cc0a338d675c8fc3fcbbd313b696c660a85fa13ec9fa13ac8e8dbce8335575\ +608d5962ecb516b9ac186206e1ffb971924e9301e6fc220d0769ea1cd954e2fd\ +dc591ea026e369509d427ad062b81ca5e8873432a0d7a031b7f26702840fbb5e\ +5e9e6c8794dbec841822ca92aea2a22709182a3cda136b7b3569d85be6213817\ +06b2852b7de3e20907739958726334ad0c2c3b7327d0060b3f6cd319bf6666e0\ +9de3ee588abb948a6df37d5ac2b18c82d63ca0a0dcc6f1c1e2ae609999f60738\ +714df767fbf14b12b7a002ce0dad86f8adf777ff7ccc9b08180faa0d96b44023\ +3ca5398525eaaa9afba9e0ea4f2cfbf5a3e868f99ddc1a86ee36baf2ab56f9b0\ +b1ff1ff591033e579847267b9557217e0991d2c90e61f7e58321d9bdaba96c9c\ +63e9d3924f0a8c7ac6d4fc94d74d7bc1a96aafad76fca0fa4017d76f00f5cb5e\ +96058fafb57caf07cbcf665fea359cfa2cd4084796e3ea2ccf30bbe6e8f7efea\ +60190fcf2700d1d27b80ff53d8071aeee1ed8708617c92d821f83c9a7ea90c72\ +f19a58e9179cbed5f4f86a80c28e0fbc3fac50d5eea3117df747ab076044f1ef\ +61c7bb95ab31ca2f4f6e61d19e906230694158df40a72fb748dd79d0fd0617b7\ +24b23c6d0569d170731ee07dfd637820f10fbe860a179f2a24775b1f27a2e528\ +a5808d13cc3f995d2cf0c4a832915e19bd6293bfae8eeabcf85de223c4dea84f\ +0d095815cd34ab885d6c50816bf8fd07d4e58aa8c8fbf34344fc3279c1efa142\ +68471ff263f121bc501439c9fe1ae45c946b348a00535ae451d17f3edcecea67\ +5a7dde387813246bb8312147163f813159413fd550e00204c441b0eaf4d12c79\ +520a3d3bd75b00e20a5284457fc3999ac7ce1f1202e5bd651047c74eac7ff92d\ +7f214d6583304f6dda309a01230198b1e656c9707f2f27663c1855771af7f449\ +0e3f3f8da53f0492654a3c40d15620e2fd2a68658ecaa8fb5601775a393878a3\ +110d75e6b968db8eb81c2ecba5852b2eaf7f9b8967b60f92ee4af138a5e777b7\ +aad802e39d7237a17b4a79d9a467a4be1be5121de907400ee5586f0f94bed1db\ +35dcd7995ec93b49b0f6dc7a1e3e4cc0ad1945e60dbe0d24948eb94ddbc45e20\ +fe0bea593df4e6d38647fb623df65f6fbd1e36f318decf77824abd6bdf95eb8f\ +a5f29b650f36b77a305bf9c15b034a7ce1f482ccba079171a6476863a70bf49f\ +cc488177e461837c64d5f5419ae0a344010df2d6edb170b1461ef27024199b15\ +44144dc327eb225f1ee99ab4f07bf2f934042f2df86252c4058212b2e5cf35dd\ +14df206c1dba5445d41f211911e1053813a09e7fea3d5de5cac92acfe36b3ef6\ +8d4767c52a31c8ccba0eaa85874892d813ae601db1ffd5cd42ec1e98534056e2\ +753b5fa30f993016b787de9620a1242986370e005ff4495315c2b1aedb59a32e\ +47be953ea41f15fbe7a115d10328f67e59c538948ceef3f4a338a030ad198b2f\ +c89f067b336f28085a4ca061a38ae6190de48981de1c942ea83a9143b1faf94c\ +2f462a9de5d14b915bfc52e916d16f11cf59a28a3d933fedb48ac06b7cdd29a0\ +720ed851863bafe7a149f403881afe46b940ca37c29b7e49a730b28404179449\ +73274553b70fb11da65acc1c5420677288c624e67542f230da340d1e9b8dc5a1\ +90b69bf5e67e77929250a802f07cdf0716db567209774367aae32e0c1e90928f\ +61c43eaa372f1e9ec70aa0dd506734d23825213edaf184a24a1bb128811db664\ +783cb27cac1edd074d79d1259f84da9e0e5c75923a4dbfaa8a6283dd2279ba69\ +bcd1d78970d7a54a0d31c44071cbf05527010e2ff808cadefd74d906a8ad8c32\ +a01845d3ad78bc6ed96a688dfff171d80d931409d94c83da2bc54ad9790e9a6b\ +a5093384850090a961572f6fdb929a1a6baa98c015e95b0a6da10de04b8471c1\ +aeac19b6c887c1c81dad641d55ab1a29250d14dc41a042f83eb8a6bddcb662a9\ +3e00cf6adaed95cb52b36692f43a8e9b85ba7723d70e5ada851a16fe102ee1c6\ +d3bf8be1634ade9fa6b44626c734788b3aed0c287ab7e80ae5fc1451ddb037c0\ +f729309209226022f13e6f8aa592445db33bb1f29101e0df15db15df0bab6411\ +5bc12f0bbf430551473dbd274db2eea9905eab75f290ecbd903b675f1ad9ac2f\ +2196d00139e7671ac8b95a8cc8e244511d481863b509e5bb7573b6ce49cf0fc9\ +53de75523ca31a64012d11bb7f60f1f67b199a4f2013f6ea3808e2639eb5f263\ +1c19568bcf36071235de8ae7b2d5815e2e0a2e81098a6b4d6179e29ed0a92bdf\ +585a2905f0496ba58eb3d740efa54b664d1a6134fed9fede636504aa691e08e4 +Test: Encrypt +Test: Decrypt @@ -21,7 +21,7 @@ ARC4_Base::~ARC4_Base() m_x = m_y = 0; } -void ARC4_Base::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int keyLen) +void ARC4_Base::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int keyLen, const byte *iv) { AssertValidKeyLength(keyLen); @@ -27,7 +27,7 @@ public: typedef SymmetricCipherFinalTemplate<ARC4_Base> Decryption; protected: - void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length); + void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv); virtual unsigned int GetDefaultDiscardBytes() const {return 0;} FixedSizeSecBlock<byte, 256> m_state; diff --git a/cryptlib.cpp b/cryptlib.cpp index e3fe2d5f..07dd87c0 100644 --- a/cryptlib.cpp +++ b/cryptlib.cpp @@ -57,6 +57,28 @@ void SimpleKeyingInterface::ThrowIfInvalidKeyLength(const Algorithm &algorithm, throw InvalidKeyLength(algorithm.AlgorithmName(), length); } +void SimpleKeyingInterface::ThrowIfResynchronizable() +{ + if (IsResynchronizable()) + throw InvalidArgument("SimpleKeyingInterface: this object requires an IV"); +} + +void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv) +{ + if (!iv && !(IVRequirement() == INTERNALLY_GENERATED_IV || IVRequirement() == STRUCTURED_IV || !IsResynchronizable())) + throw InvalidArgument("SimpleKeyingInterface: this object cannot use a null IV"); +} + +const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms) +{ + const byte *iv; + if (params.GetValue(Name::IV(), iv)) + ThrowIfInvalidIV(iv); + else + ThrowIfResynchronizable(); + return iv; +} + void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, unsigned int numberOfBlocks) const { unsigned int blockSize = BlockSize(); @@ -381,6 +381,9 @@ public: protected: void ThrowIfInvalidKeyLength(const Algorithm &algorithm, unsigned int length); + void ThrowIfResynchronizable(); // to be called when no IV is passed + void ThrowIfInvalidIV(const byte *iv); // check for NULL IV if it can't be used + const byte * GetIVAndThrowIfInvalid(const NameValuePairs ¶ms); inline void AssertValidKeyLength(unsigned int length) const { diff --git a/datatest.cpp b/datatest.cpp index 50b26fe2..13077602 100644 --- a/datatest.cpp +++ b/datatest.cpp @@ -197,7 +197,7 @@ privateKeyTests: } } -void TestEncryptionScheme(TestData &v) +void TestAsymmetricCipher(TestData &v) { std::string name = GetRequiredDatum(v, "Name"); std::string test = GetRequiredDatum(v, "Test"); @@ -237,6 +237,41 @@ void TestEncryptionScheme(TestData &v) } } +void TestSymmetricCipher(TestData &v) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + std::string key = GetDecodedDatum(v, "Key"); + std::string iv = GetDecodedDatum(v, "IV"); + std::string ciphertext = GetDecodedDatum(v, "Ciphertext"); + std::string plaintext = GetDecodedDatum(v, "Plaintext"); + + if (test == "Encrypt") + { + std::auto_ptr<SymmetricCipher> encryptor(ObjectFactoryRegistry<SymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str())); + encryptor->SetKeyWithIV((const byte *)key.data(), key.size(), (const byte *)iv.data()); + std::string encrypted; + StringSource ss(plaintext, true, new StreamTransformationFilter(*encryptor, new StringSink(encrypted), StreamTransformationFilter::NO_PADDING)); + if (encrypted != ciphertext) + SignalTestFailure(); + } + else if (test == "Decrypt") + { + std::auto_ptr<SymmetricCipher> decryptor(ObjectFactoryRegistry<SymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str())); + decryptor->SetKeyWithIV((const byte *)key.data(), key.size(), (const byte *)iv.data()); + std::string decrypted; + StringSource ss(ciphertext, true, new StreamTransformationFilter(*decryptor, new StringSink(decrypted), StreamTransformationFilter::NO_PADDING)); + if (decrypted != plaintext) + SignalTestFailure(); + } + else + { + SignalTestError(); + assert(false); + } +} + void TestDigestOrMAC(TestData &v, bool testDigest) { std::string name = GetRequiredDatum(v, "Name"); @@ -391,8 +426,10 @@ void TestDataFile(const std::string &filename, unsigned int &totalTests, unsigne { if (algType == "Signature") TestSignatureScheme(v); + else if (algType == "SymmetricCipher") + TestSymmetricCipher(v); else if (algType == "AsymmetricCipher") - TestEncryptionScheme(v); + TestAsymmetricCipher(v); else if (algType == "MessageDigest") TestDigestOrMAC(v, true); else if (algType == "MAC") @@ -24,7 +24,7 @@ public: }; -template <class AbstractClass> +template <class AbstractClass, int instance=0> class ObjectFactoryRegistry { public: @@ -55,38 +55,46 @@ public: } // VC60 workaround: use "..." to prevent this function from being inlined - static ObjectFactoryRegistry<AbstractClass> & Registry(...); + static ObjectFactoryRegistry<AbstractClass, instance> & Registry(...); private: typedef std::map<std::string, ObjectFactory<AbstractClass> *> Map; Map m_map; }; -template <class AbstractClass> -ObjectFactoryRegistry<AbstractClass> & ObjectFactoryRegistry<AbstractClass>::Registry(...) +template <class AbstractClass, int instance> +ObjectFactoryRegistry<AbstractClass, instance> & ObjectFactoryRegistry<AbstractClass, instance>::Registry(...) { - static ObjectFactoryRegistry<AbstractClass> s_registry; + static ObjectFactoryRegistry<AbstractClass, instance> s_registry; return s_registry; } -template <class AbstractClass, class ConcreteClass> -void RegisterDefaultFactoryFor(const char *name, AbstractClass *Dummy1=NULL, ConcreteClass *Dummy2=NULL) +template <class AbstractClass, class ConcreteClass, int instance = 0> +struct RegisterDefaultFactoryFor { +RegisterDefaultFactoryFor(const char *name) { - ObjectFactoryRegistry<AbstractClass>::Registry().RegisterFactory(name, new DefaultObjectFactory<AbstractClass, ConcreteClass>); -} + ObjectFactoryRegistry<AbstractClass, instance>::Registry().RegisterFactory(name, new DefaultObjectFactory<AbstractClass, ConcreteClass>); +}}; template <class SchemeClass> -void RegisterPublicKeyCryptoSystemDefaultFactories(const char *name, SchemeClass *dummy=NULL) +void RegisterAsymmetricCipherDefaultFactories(const char *name, SchemeClass *dummy=NULL) { - RegisterDefaultFactoryFor<PK_Encryptor, CPP_TYPENAME SchemeClass::Encryptor>(name); - RegisterDefaultFactoryFor<PK_Decryptor, CPP_TYPENAME SchemeClass::Decryptor>(name); + RegisterDefaultFactoryFor<PK_Encryptor, CPP_TYPENAME SchemeClass::Encryptor>((const char *)name); + RegisterDefaultFactoryFor<PK_Decryptor, CPP_TYPENAME SchemeClass::Decryptor>((const char *)name); } template <class SchemeClass> void RegisterSignatureSchemeDefaultFactories(const char *name, SchemeClass *dummy=NULL) { - RegisterDefaultFactoryFor<PK_Signer, CPP_TYPENAME SchemeClass::Signer>(name); - RegisterDefaultFactoryFor<PK_Verifier, CPP_TYPENAME SchemeClass::Verifier>(name); + RegisterDefaultFactoryFor<PK_Signer, CPP_TYPENAME SchemeClass::Signer>((const char *)name); + RegisterDefaultFactoryFor<PK_Verifier, CPP_TYPENAME SchemeClass::Verifier>((const char *)name); +} + +template <class SchemeClass> +void RegisterSymmetricCipherDefaultFactories(const char *name, SchemeClass *dummy=NULL) +{ + RegisterDefaultFactoryFor<SymmetricCipher, CPP_TYPENAME SchemeClass::Encryption, ENCRYPTION>((const char *)name); + RegisterDefaultFactoryFor<SymmetricCipher, CPP_TYPENAME SchemeClass::Decryption, DECRYPTION>((const char *)name); } NAMESPACE_END @@ -32,7 +32,7 @@ template class AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstrac void CipherModeBase::SetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) { - UncheckedSetKey(params, key, length); // the underlying cipher will check the key length + UncheckedSetKey(params, key, length, GetIVAndThrowIfInvalid(params)); // the underlying cipher will check the key length } void CipherModeBase::GetNextIV(byte *IV) @@ -44,22 +44,6 @@ void CipherModeBase::GetNextIV(byte *IV) memcpy(IV, m_register, BlockSize()); } -void CipherModeBase::SetIV(const byte *iv) -{ - if (iv) - Resynchronize(iv); - else if (IsResynchronizable()) - { - if (!CanUseStructuredIVs()) - throw InvalidArgument("CipherModeBase: this cipher mode cannot use a null IV"); - - // use all zeros as default IV - SecByteBlock iv(BlockSize()); - memset(iv, 0, iv.size()); - Resynchronize(iv); - } -} - void CTR_ModePolicy::SeekToIteration(dword iterationCount) { int carry=0; @@ -126,17 +110,17 @@ void CTR_ModePolicy::OperateKeystream(KeystreamOperation operation, byte *output void CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv) { unsigned int s = BlockSize(); - memcpy(m_register, iv, s); + CopyOrZero(m_register, iv, s); m_counterArray.New(s * m_cipher->OptimalNumberOfParallelBlocks()); - memcpy(m_counterArray, iv, s); + CopyOrZero(m_counterArray, iv, s); } -void BlockOrientedCipherModeBase::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) +void BlockOrientedCipherModeBase::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv) { m_cipher->SetKey(key, length, params); ResizeBuffers(); - const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL); - SetIV(iv); + if (IsResynchronizable()) + Resynchronize(iv); } void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inString, unsigned int length) @@ -47,7 +47,6 @@ public: protected: inline unsigned int BlockSize() const {assert(m_register.size() > 0); return m_register.size();} - void SetIV(const byte *iv); virtual void SetFeedbackSize(unsigned int feedbackSize) { if (!(feedbackSize == 0 || feedbackSize == BlockSize())) @@ -57,7 +56,7 @@ protected: { m_register.New(m_cipher->BlockSize()); } - virtual void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) =0; + virtual void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv) =0; BlockCipher *m_cipher; SecByteBlock m_register; @@ -73,8 +72,6 @@ class ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE ResizeBuffers(); int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0); SetFeedbackSize(feedbackSize); - const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL); - SetIV(iv); } }; @@ -113,6 +110,14 @@ protected: unsigned int m_feedbackSize; }; +inline void CopyOrZero(void *dest, const void *src, size_t s) +{ + if (src) + memcpy(dest, src, s); + else + memset(dest, 0, s); +} + class OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy> { unsigned int GetBytesPerIteration() const {return BlockSize();} @@ -124,7 +129,7 @@ class OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPol } void CipherResynchronize(byte *keystreamBuffer, const byte *iv) { - memcpy(keystreamBuffer, iv, BlockSize()); + CopyOrZero(keystreamBuffer, iv, BlockSize()); } bool IsRandomAccess() const {return false;} IV_Requirement IVRequirement() const {return STRUCTURED_IV;} @@ -151,7 +156,7 @@ class CTR_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPol class BlockOrientedCipherModeBase : public CipherModeBase { public: - void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length); + void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv); unsigned int MandatoryBlockSize() const {return BlockSize();} bool IsRandomAccess() const {return false;} bool IsSelfInverting() const {return false;} @@ -202,9 +207,9 @@ public: void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length); protected: - void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) + void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv) { - CBC_Encryption::UncheckedSetKey(params, key, length); + CBC_Encryption::UncheckedSetKey(params, key, length, iv); m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL); } @@ -250,7 +255,7 @@ public: CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length, const byte *iv, int feedbackSize = 0) { m_cipher = &m_object; - SetKey(key, length, MakeParameters("IV", iv)("FeedbackSize", feedbackSize)); + SetKey(key, length, MakeParameters(Name::IV(), iv)(Name::FeedbackSize(), feedbackSize)); } }; @@ -259,12 +264,21 @@ template <class BASE> class CipherModeFinalTemplate_ExternalCipher : public BASE { public: - CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv = NULL, int feedbackSize = 0) + CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher) + { + ThrowIfResynchronizable(); + m_cipher = &cipher; + ResizeBuffers(); + } + + CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv, int feedbackSize = 0) { + ThrowIfInvalidIV(iv); m_cipher = &cipher; ResizeBuffers(); SetFeedbackSize(feedbackSize); - SetIV(iv); + if (IsResynchronizable()) + Resynchronize(iv); } }; @@ -82,7 +82,7 @@ struct PanamaCipherInfo : public VariableKeyLength<32, 32, 64, 32, SimpleKeyingI //! . template <class B> -class PanamaCipherPolicy : public AdditiveCipherConcretePolicy<word32, 32>, +class PanamaCipherPolicy : public AdditiveCipherConcretePolicy<word32, 8>, public PanamaCipherInfo<B>, protected Panama<B> { diff --git a/regtest.cpp b/regtest.cpp index b01351fc..d691d46a 100644 --- a/regtest.cpp +++ b/regtest.cpp @@ -9,6 +9,7 @@ #include "rsa.h" #include "ripemd.h" #include "dsa.h" +#include "seal.h" USING_NAMESPACE(CryptoPP) @@ -22,8 +23,8 @@ void RegisterFactories() RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<MD5> >("HMAC(MD5)"); RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<SHA1> >("HMAC(SHA-1)"); RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<RIPEMD160> >("HMAC(RIPEMD-160)"); - RegisterPublicKeyCryptoSystemDefaultFactories<RSAES<OAEP<SHA1> > >("RSA/OAEP-MGF1(SHA-1)"); - RegisterPublicKeyCryptoSystemDefaultFactories<DLIES<> >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)"); + RegisterAsymmetricCipherDefaultFactories<RSAES<OAEP<SHA1> > >("RSA/OAEP-MGF1(SHA-1)"); + RegisterAsymmetricCipherDefaultFactories<DLIES<> >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)"); RegisterSignatureSchemeDefaultFactories<DSA>("DSA(1363)"); RegisterSignatureSchemeDefaultFactories<NR<SHA1> >("NR(1363)/EMSA1(SHA-1)"); RegisterSignatureSchemeDefaultFactories<GDSA<SHA1> >("DSA-1363/EMSA1(SHA-1)"); @@ -32,4 +33,5 @@ void RegisterFactories() RegisterSignatureSchemeDefaultFactories<ESIGN<SHA1> >("ESIGN/EMSA5-MGF1(SHA-1)"); RegisterSignatureSchemeDefaultFactories<RWSS<P1363_EMSA2, SHA1> >("RW/EMSA2(SHA-1)"); RegisterSignatureSchemeDefaultFactories<RSASS<PSS, SHA1> >("RSA/PSS-MGF1(SHA-1)"); + RegisterSymmetricCipherDefaultFactories<SEAL<> >("SEAL-3.0-BE"); } @@ -69,7 +69,7 @@ void SEAL_Policy<B>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, template <class B> void SEAL_Policy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *IV) { - m_outsideCounter = UnalignedGetWord<word32>(BIG_ENDIAN_ORDER, IV); + m_outsideCounter = IV ? UnalignedGetWord<word32>(BIG_ENDIAN_ORDER, IV) : 0; m_startCount = m_outsideCounter; m_insideCounter = 0; } @@ -12,7 +12,7 @@ struct SEAL_Info : public FixedKeyLength<20, SimpleKeyingInterface::INTERNALLY_G }; template <class B = BigEndian> -class SEAL_Policy : public AdditiveCipherConcretePolicy<word32, 1024>, public SEAL_Info<B> +class SEAL_Policy : public AdditiveCipherConcretePolicy<word32, 256>, public SEAL_Info<B> { public: unsigned int IVSize() const {return 4;} @@ -30,6 +30,7 @@ #include "seckey.h" #include "secblock.h" +#include "argnames.h" NAMESPACE_BEGIN(CryptoPP) @@ -134,7 +135,7 @@ public: typedef typename BASE::PolicyInterface PolicyInterface; protected: - void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length); + void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv); unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();} @@ -226,7 +227,7 @@ public: protected: virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length) =0; - void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length); + void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv); unsigned int m_leftOver; }; @@ -255,31 +256,38 @@ public: SymmetricCipherFinalTemplate(const byte *key, unsigned int length) {SetKey(key, length);} SymmetricCipherFinalTemplate(const byte *key, unsigned int length, const byte *iv) - {SetKey(key, length); Resynchronize(iv);} + {SetKeyWithIV(key, length, iv);} void SetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms = g_nullNameValuePairs) { ThrowIfInvalidKeyLength(length); - UncheckedSetKey(params, key, length); + UncheckedSetKey(params, key, length, GetIVAndThrowIfInvalid(params)); } Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinalTemplate<BASE, INFO>(*this));} }; template <class S> -void AdditiveCipherTemplate<S>::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) +void AdditiveCipherTemplate<S>::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv) { PolicyInterface &policy = AccessPolicy(); policy.CipherSetKey(params, key, length); - m_buffer.New(GetBufferByteSize(policy)); m_leftOver = 0; + m_buffer.New(GetBufferByteSize(policy)); + + if (IsResynchronizable()) + policy.CipherResynchronize(m_buffer, iv); } template <class BASE> -void CFB_CipherTemplate<BASE>::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) +void CFB_CipherTemplate<BASE>::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length, const byte *iv) { PolicyInterface &policy = AccessPolicy(); policy.CipherSetKey(params, key, length); + + if (IsResynchronizable()) + policy.CipherResynchronize(iv); + m_leftOver = policy.GetBytesPerIteration(); } diff --git a/validat1.cpp b/validat1.cpp index 5619589e..c71a0f4b 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -1240,8 +1240,7 @@ bool ValidateSEAL() cout << "\nSEAL validation suite running...\n\n"; - SEAL<>::Encryption seal(key); - seal.Resynchronize(iv); + SEAL<>::Encryption seal(key, sizeof(key), iv); unsigned int size = sizeof(input); bool pass = true; |