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 diff --git a/arc4.cpp b/arc4.cpp index 7d8d05a5..407c75c6 100644 --- a/arc4.cpp +++ b/arc4.cpp @@ -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); diff --git a/arc4.h b/arc4.h index 51de9f12..cfb7de69 100644 --- a/arc4.h +++ b/arc4.h @@ -27,7 +27,7 @@ public: typedef SymmetricCipherFinalTemplate 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 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(); diff --git a/cryptlib.h b/cryptlib.h index 27783971..31e32e8f 100644 --- a/cryptlib.h +++ b/cryptlib.h @@ -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 encryptor(ObjectFactoryRegistry::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 decryptor(ObjectFactoryRegistry::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") diff --git a/factory.h b/factory.h index 893a731f..1dd0bdc3 100644 --- a/factory.h +++ b/factory.h @@ -24,7 +24,7 @@ public: }; -template +template class ObjectFactoryRegistry { public: @@ -55,38 +55,46 @@ public: } // VC60 workaround: use "..." to prevent this function from being inlined - static ObjectFactoryRegistry & Registry(...); + static ObjectFactoryRegistry & Registry(...); private: typedef std::map *> Map; Map m_map; }; -template -ObjectFactoryRegistry & ObjectFactoryRegistry::Registry(...) +template +ObjectFactoryRegistry & ObjectFactoryRegistry::Registry(...) { - static ObjectFactoryRegistry s_registry; + static ObjectFactoryRegistry s_registry; return s_registry; } -template -void RegisterDefaultFactoryFor(const char *name, AbstractClass *Dummy1=NULL, ConcreteClass *Dummy2=NULL) +template +struct RegisterDefaultFactoryFor { +RegisterDefaultFactoryFor(const char *name) { - ObjectFactoryRegistry::Registry().RegisterFactory(name, new DefaultObjectFactory); -} + ObjectFactoryRegistry::Registry().RegisterFactory(name, new DefaultObjectFactory); +}}; template -void RegisterPublicKeyCryptoSystemDefaultFactories(const char *name, SchemeClass *dummy=NULL) +void RegisterAsymmetricCipherDefaultFactories(const char *name, SchemeClass *dummy=NULL) { - RegisterDefaultFactoryFor(name); - RegisterDefaultFactoryFor(name); + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); } template void RegisterSignatureSchemeDefaultFactories(const char *name, SchemeClass *dummy=NULL) { - RegisterDefaultFactoryFor(name); - RegisterDefaultFactoryFor(name); + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); +} + +template +void RegisterSymmetricCipherDefaultFactories(const char *name, SchemeClass *dummy=NULL) +{ + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); } NAMESPACE_END diff --git a/modes.cpp b/modes.cpp index 70c23234..09c370ee 100644 --- a/modes.cpp +++ b/modes.cpp @@ -32,7 +32,7 @@ template class AdditiveCipherTemplateOptimalNumberOfParallelBlocks()); - 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) diff --git a/modes.h b/modes.h index 46e8dd26..9a94f379 100644 --- a/modes.h +++ b/modes.h @@ -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 { unsigned int GetBytesPerIteration() const {return BlockSize();} @@ -124,7 +129,7 @@ class OFB_ModePolicy : public ModePolicyCommonTemplate 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); } }; diff --git a/panama.h b/panama.h index a24113d0..30b6390c 100644 --- a/panama.h +++ b/panama.h @@ -82,7 +82,7 @@ struct PanamaCipherInfo : public VariableKeyLength<32, 32, 64, 32, SimpleKeyingI //! . template -class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, +class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, public PanamaCipherInfo, protected Panama { 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 >("HMAC(MD5)"); RegisterDefaultFactoryFor >("HMAC(SHA-1)"); RegisterDefaultFactoryFor >("HMAC(RIPEMD-160)"); - RegisterPublicKeyCryptoSystemDefaultFactories > >("RSA/OAEP-MGF1(SHA-1)"); - RegisterPublicKeyCryptoSystemDefaultFactories >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)"); + RegisterAsymmetricCipherDefaultFactories > >("RSA/OAEP-MGF1(SHA-1)"); + RegisterAsymmetricCipherDefaultFactories >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)"); RegisterSignatureSchemeDefaultFactories("DSA(1363)"); RegisterSignatureSchemeDefaultFactories >("NR(1363)/EMSA1(SHA-1)"); RegisterSignatureSchemeDefaultFactories >("DSA-1363/EMSA1(SHA-1)"); @@ -32,4 +33,5 @@ void RegisterFactories() RegisterSignatureSchemeDefaultFactories >("ESIGN/EMSA5-MGF1(SHA-1)"); RegisterSignatureSchemeDefaultFactories >("RW/EMSA2(SHA-1)"); RegisterSignatureSchemeDefaultFactories >("RSA/PSS-MGF1(SHA-1)"); + RegisterSymmetricCipherDefaultFactories >("SEAL-3.0-BE"); } diff --git a/seal.cpp b/seal.cpp index 97362233..a478f9a5 100644 --- a/seal.cpp +++ b/seal.cpp @@ -69,7 +69,7 @@ void SEAL_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, template void SEAL_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV) { - m_outsideCounter = UnalignedGetWord(BIG_ENDIAN_ORDER, IV); + m_outsideCounter = IV ? UnalignedGetWord(BIG_ENDIAN_ORDER, IV) : 0; m_startCount = m_outsideCounter; m_insideCounter = 0; } diff --git a/seal.h b/seal.h index 0e9f025d..4fc7e887 100644 --- a/seal.h +++ b/seal.h @@ -12,7 +12,7 @@ struct SEAL_Info : public FixedKeyLength<20, SimpleKeyingInterface::INTERNALLY_G }; template -class SEAL_Policy : public AdditiveCipherConcretePolicy, public SEAL_Info +class SEAL_Policy : public AdditiveCipherConcretePolicy, public SEAL_Info { public: unsigned int IVSize() const {return 4;} diff --git a/strciphr.h b/strciphr.h index 2a297bba..8b3c9aa5 100644 --- a/strciphr.h +++ b/strciphr.h @@ -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(new SymmetricCipherFinalTemplate(*this));} }; template -void AdditiveCipherTemplate::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) +void AdditiveCipherTemplate::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 -void CFB_CipherTemplate::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) +void CFB_CipherTemplate::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;