diff options
175 files changed, 4332 insertions, 2253 deletions
diff --git a/botan_version.py b/botan_version.py index 1d82cb588..a44619e71 100644 --- a/botan_version.py +++ b/botan_version.py @@ -1,6 +1,9 @@ release_major = 1 -release_minor = 9 -release_patch = 17 +release_minor = 10 +release_patch = 2 + +release_vc_rev = None +release_so_abi_rev = 0 release_datestamp = 0 diff --git a/checks/dolook.cpp b/checks/dolook.cpp index 1015f4240..a8e08a96b 100644 --- a/checks/dolook.cpp +++ b/checks/dolook.cpp @@ -55,6 +55,8 @@ using namespace Botan; #include "common.h" +namespace { + /* A weird little hack to fit PBKDF algorithms into the validation * suite You probably wouldn't ever want to actually use the PBKDF * algorithms like this, the raw PBKDF interface is more convenient @@ -279,6 +281,8 @@ Filter* lookup_encoder(const std::string& algname) return 0; } +} + Filter* lookup(const std::string& algname, const std::vector<std::string>& params) { diff --git a/checks/ec_tests.cpp b/checks/ec_tests.cpp index bad0d8912..8ed975603 100644 --- a/checks/ec_tests.cpp +++ b/checks/ec_tests.cpp @@ -5,12 +5,16 @@ */ -#include <botan/build.h> +#include <botan/rng.h> + +#if defined(BOTAN_HAS_ECC_GROUP) + #include <botan/bigint.h> #include <botan/numthry.h> #include <botan/curve_gfp.h> #include <botan/point_gfp.h> -#include <botan/ecdsa.h> +#include <botan/ec_group.h> +#include <botan/reducer.h> #include <botan/oids.h> using namespace Botan; @@ -22,6 +26,7 @@ using namespace Botan; #include "validate.h" #include "common.h" + #define CHECK_MESSAGE(expr, print) try { if(!(expr)) std::cout << print << "\n"; } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << "\n"; } #define CHECK(expr) try { if(!(expr)) std::cout << #expr << "\n"; } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << "\n"; } @@ -38,7 +43,7 @@ PointGFp create_random_point(RandomNumberGenerator& rng, { const BigInt& p = curve.get_p(); - const Modular_Reducer& mod_p = curve.mod_p(); + Modular_Reducer mod_p(p); while(true) { @@ -813,3 +818,10 @@ void do_ec_tests(RandomNumberGenerator& rng) std::cout << std::endl; } +#else + +void do_ec_tests(Botan::RandomNumberGenerator& rng) + { + } + +#endif diff --git a/checks/ecdsa.cpp b/checks/ecdsa.cpp index 58f76c9ba..5cf353e58 100644 --- a/checks/ecdsa.cpp +++ b/checks/ecdsa.cpp @@ -172,12 +172,12 @@ bool test_ec_sign(RandomNumberGenerator& rng) PK_Signer signer(priv_key, "EMSA1(SHA-224)"); PK_Verifier verifier(priv_key, "EMSA1(SHA-224)"); - for(u32bit i = 0; i != 256; ++i) - signer.update((byte)i); + for(size_t i = 0; i != 256; ++i) + signer.update(static_cast<byte>(i)); SecureVector<byte> sig = signer.signature(rng); for(u32bit i = 0; i != 256; ++i) - verifier.update((byte)i); + verifier.update(static_cast<byte>(i)); if(!verifier.check_signature(sig)) { std::cout << "ECDSA self-test failed!"; @@ -186,7 +186,7 @@ bool test_ec_sign(RandomNumberGenerator& rng) // now check valid signature, different input for(u32bit i = 1; i != 256; ++i) //starting from 1 - verifier.update((byte)i); + verifier.update(static_cast<byte>(i)); if(verifier.check_signature(sig)) { @@ -198,7 +198,7 @@ bool test_ec_sign(RandomNumberGenerator& rng) sig[sig.size()/2]++; for(u32bit i = 0; i != 256; ++i) - verifier.update((byte)i); + verifier.update(static_cast<byte>(i)); if(verifier.check_signature(sig)) { diff --git a/checks/nist_tests/x509test.cpp b/checks/nist_tests/x509test.cpp index d89e7c341..66b274c6c 100644 --- a/checks/nist_tests/x509test.cpp +++ b/checks/nist_tests/x509test.cpp @@ -1,7 +1,7 @@ /* - Code to run the X.509v3 processing tests described in "Conformance Testing of - Relying Party Client Certificate Path Proccessing Logic", which is available - on NIST's web site. + Code to run the X.509v3 processing tests described in "Conformance + Testing of Relying Party Client Certificate Path Proccessing Logic", + which is available on NIST's web site. */ #include <botan/x509path.h> @@ -18,10 +18,6 @@ using namespace Botan; #include <dirent.h> -#define POLICY_TEST1 1000 -#define POLICY_TEST2 2000 -#define POLICY_TEST3 3000 - std::vector<std::string> dir_listing(const std::string&); void run_one_test(u32bit, X509_Code, @@ -263,13 +259,14 @@ void populate_expected_results() expected_results[33] = VERIFIED; /* - Policy tests: a little trickier because there are other inputs which - affect the result. + Policy tests: a little trickier because there are other inputs + which affect the result. - In the case of the tests currently in the suite, the default method (with - acceptable policy being "any-policy" and with no explict policy required), - will almost always result in a verified status. This is not particularly - helpful. So, we do several different tests for each test set: + In the case of the tests currently in the suite, the default + method (with acceptable policy being "any-policy" and with no + explict policy required), will almost always result in a verified + status. This is not particularly helpful. So, we should do several + different tests for each test set: 1) With the user policy as any-policy and no explicit policy 2) With the user policy as any-policy and an explicit policy required @@ -281,88 +278,28 @@ void populate_expected_results() This provides reasonably good coverage of the possible outcomes. */ - /* expected_results[34] = VERIFIED; - expected_results[34+POLICY_TEST1] = ; - expected_results[34+POLICY_TEST2] = ; - expected_results[34+POLICY_TEST3] = ; expected_results[35] = VERIFIED; - expected_results[35+POLICY_TEST1] = ; - expected_results[35+POLICY_TEST2] = ; - expected_results[35+POLICY_TEST3] = ; expected_results[36] = VERIFIED; - expected_results[36+POLICY_TEST1] = ; - expected_results[36+POLICY_TEST2] = ; - expected_results[36+POLICY_TEST3] = ; expected_results[37] = VERIFIED; - expected_results[37+POLICY_TEST1] = ; - expected_results[37+POLICY_TEST2] = ; - expected_results[37+POLICY_TEST3] = ; expected_results[38] = VERIFIED; - expected_results[38+POLICY_TEST1] = ; - expected_results[38+POLICY_TEST2] = ; - expected_results[38+POLICY_TEST3] = ; expected_results[39] = VERIFIED; - expected_results[39+POLICY_TEST1] = ; - expected_results[39+POLICY_TEST2] = ; - expected_results[39+POLICY_TEST3] = ; expected_results[40] = VERIFIED; - expected_results[40+POLICY_TEST1] = ; - expected_results[40+POLICY_TEST2] = ; - expected_results[40+POLICY_TEST3] = ; expected_results[41] = VERIFIED; - expected_results[41+POLICY_TEST1] = ; - expected_results[41+POLICY_TEST2] = ; - expected_results[41+POLICY_TEST3] = ; expected_results[42] = VERIFIED; - expected_results[42+POLICY_TEST1] = ; - expected_results[42+POLICY_TEST2] = ; - expected_results[42+POLICY_TEST3] = ; expected_results[43] = VERIFIED; - expected_results[43+POLICY_TEST1] = ; - expected_results[43+POLICY_TEST2] = ; - expected_results[43+POLICY_TEST3] = ; expected_results[44] = VERIFIED; - expected_results[44+POLICY_TEST1] = ; - expected_results[44+POLICY_TEST2] = ; - expected_results[44+POLICY_TEST3] = ; - expected_results[45] = EXPLICT_POLICY_REQUIRED; - expected_results[45+POLICY_TEST1] = ; - expected_results[45+POLICY_TEST2] = ; - expected_results[45+POLICY_TEST3] = ; - expected_results[46] = ACCEPT; - expected_results[46+POLICY_TEST1] = ; - expected_results[46+POLICY_TEST2] = ; - expected_results[46+POLICY_TEST3] = ; - expected_results[47] = EXPLICT_POLICY_REQUIRED; - expected_results[47+POLICY_TEST1] = ; - expected_results[47+POLICY_TEST2] = ; - expected_results[47+POLICY_TEST3] = ; + + //expected_results[45] = EXPLICT_POLICY_REQUIRED; + //expected_results[46] = ACCEPT; + //expected_results[47] = EXPLICT_POLICY_REQUIRED; + expected_results[48] = VERIFIED; - expected_results[48+POLICY_TEST1] = ; - expected_results[48+POLICY_TEST2] = ; - expected_results[48+POLICY_TEST3] = ; expected_results[49] = VERIFIED; - expected_results[49+POLICY_TEST1] = ; - expected_results[49+POLICY_TEST2] = ; - expected_results[49+POLICY_TEST3] = ; expected_results[50] = VERIFIED; - expected_results[50+POLICY_TEST1] = ; - expected_results[50+POLICY_TEST2] = ; - expected_results[50+POLICY_TEST3] = ; expected_results[51] = VERIFIED; - expected_results[51+POLICY_TEST1] = ; - expected_results[51+POLICY_TEST2] = ; - expected_results[51+POLICY_TEST3] = ; expected_results[52] = VERIFIED; - expected_results[52+POLICY_TEST1] = ; - expected_results[52+POLICY_TEST2] = ; - expected_results[52+POLICY_TEST3] = ; expected_results[53] = VERIFIED; - expected_results[53+POLICY_TEST1] = ; - expected_results[53+POLICY_TEST2] = ; - expected_results[53+POLICY_TEST3] = ; - */ expected_results[54] = CERT_CHAIN_TOO_LONG; expected_results[55] = CERT_CHAIN_TOO_LONG; diff --git a/checks/pk_bench.cpp b/checks/pk_bench.cpp index b0e689b0c..de8ad0730 100644 --- a/checks/pk_bench.cpp +++ b/checks/pk_bench.cpp @@ -65,6 +65,9 @@ using namespace Botan; #include <memory> #include <set> +#define BENCH_FAULT_PROT DISABLE_FAULT_PROTECTION +//#define BENCH_FAULT_PROT ENABLE_FAULT_PROTECTION + namespace { const char* ec_domains[] = { @@ -329,7 +332,7 @@ void benchmark_ecdsa(RandomNumberGenerator& rng, ECDSA_PrivateKey key(rng, params); keygen_timer.stop(); - PK_Signer sig(key, padding, IEEE_1363, DISABLE_FAULT_PROTECTION); + PK_Signer sig(key, padding, IEEE_1363, BENCH_FAULT_PROT); PK_Verifier ver(key, padding); benchmark_sig_ver(ver, sig, verify_timer, @@ -371,7 +374,7 @@ void benchmark_gost_3410(RandomNumberGenerator& rng, GOST_3410_PrivateKey key(rng, params); keygen_timer.stop(); - PK_Signer sig(key, padding, IEEE_1363, DISABLE_FAULT_PROTECTION); + PK_Signer sig(key, padding, IEEE_1363, BENCH_FAULT_PROT); PK_Verifier ver(key, padding); benchmark_sig_ver(ver, sig, verify_timer, @@ -478,7 +481,7 @@ void benchmark_dsa_nr(RandomNumberGenerator& rng, algo_name = key.algo_name(); keygen_timer.stop(); - PK_Signer sig(key, padding, IEEE_1363, DISABLE_FAULT_PROTECTION); + PK_Signer sig(key, padding, IEEE_1363, BENCH_FAULT_PROT); PK_Verifier ver(key, padding); benchmark_sig_ver(ver, sig, verify_timer, diff --git a/checks/validate.cpp b/checks/validate.cpp index d79f9783a..65317604e 100644 --- a/checks/validate.cpp +++ b/checks/validate.cpp @@ -183,19 +183,23 @@ bool test_bcrypt(RandomNumberGenerator& rng) #if defined(BOTAN_HAS_BCRYPT) std::cout << "Testing Bcrypt: " << std::flush; - const std::string input = "abc"; + bool ok = true; // Generated by jBCrypt 0.3 - const std::string fixed_hash = - "$2a$05$DfPyLs.G6.To9fXEFgUL1O6HpYw3jIXgPcl/L3Qt3jESuWmhxtmpS"; + if(!check_bcrypt("abc", + "$2a$05$DfPyLs.G6.To9fXEFgUL1O6HpYw3jIXgPcl/L3Qt3jESuWmhxtmpS")) + { + std::cout << "Fixed bcrypt test failed\n"; + ok = false; + } std::cout << "." << std::flush; - bool ok = true; - - if(!check_bcrypt(input, fixed_hash)) + // http://www.openwall.com/lists/john-dev/2011/06/19/2 + if(!check_bcrypt("\xA3", + "$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq")) { - std::cout << "Fixed bcrypt test failed\n"; + std::cout << "Fixed bcrypt test 2 failed\n"; ok = false; } @@ -203,7 +207,8 @@ bool test_bcrypt(RandomNumberGenerator& rng) for(u16bit level = 1; level != 5; ++level) { - std::string gen_hash = generate_bcrypt(input, rng, level); + const std::string input = "some test passphrase 123"; + const std::string gen_hash = generate_bcrypt(input, rng, level); if(!check_bcrypt(input, gen_hash)) { diff --git a/checks/validate.dat b/checks/validate.dat index 41e5bf61f..6b9a49e52 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -4123,6 +4123,26 @@ F0E1D2C3B4A5968778695A4B3C2D1E0F00112233445566 FEDCBA9876543210:05044B62FA52D080:\ F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677 +[Camellia] +# From RFC 3713 + +0123456789ABCDEFFEDCBA9876543210:67673138549669730857065648EABE43:\ +0123456789ABCDEFFEDCBA9876543210 + +0123456789ABCDEFFEDCBA9876543210:B4993401B3E996F84EE5CEE7D79B09B9:\ +0123456789ABCDEFFEDCBA98765432100011223344556677 + +0123456789ABCDEFFEDCBA9876543210:9ACC237DFF16D76C20EF7C919E3A7509:\ +0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF + +# From NESSIE + +00000000000000000000000000000000:6C227F749319A3AA7DA235A9BBA05A2C:\ +80000000000000000000000000000000 + +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:25DD9EB9DD67FBC6E8431F56F4FBE651:\ +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + # First one is from RFC 2144. The rest were done with OpenSSL and bits taken # from /dev/urandom [CAST-128] @@ -4406,6 +4426,61 @@ D2FD8867D50D2DFE:0000000000000004:0101010101010101 0000000000000000:E2F5728F0995013C:1002911598100201 0000000000000000:1AEAC39A61F0A464:1002911698100101 +# Tests all sboxes +01A1D6D039776742:690F5B0D9A26939B:7CA110454A1A6E57 +5CD54CA83DEF57DA:7A389D10354BD271:0131D9619DC1376E +0248D43806F67172:868EBB51CAB4599A:07A1133E4A0B2686 +51454B582DDF440A:7178876E01F19B2A:3849674C2602319E +42FD443059577FA2:AF37FB421F8C4095:04B915BA43FEB5B6 +059B5E0851CF143A:86A560F10EC6D85B:0113B970FD34F2CE +0756D8E0774761D2:0CD3DA020021DC09:0170F175468FB5E6 +762514B829BF486A:EA676B2CB7DB2B7A:43297FAD38E373FE +3BDD119049372802:DFD64A815CAF1A0F:07A7137045DA2A16 +26955F6835AF609A:5C513C9C4886C088:04689104C2FD3B2F +164D5E404F275232:0A2AEEAE3FF4AB77:37D06BB516CB7546 +6B056E18759F5CCA:EF1BF03E5DFA575A:1F08260D1AC2465E +004BD6EF09176062:88BF0DB6D70DEE56:584023641ABA6176 +480D39006EE762F2:A1F9915541020B56:025816164629B007 +437540C8698F3CFA:6FBF1CAFCFFD0556:49793EBC79B3258F +072D43A077075292:2F22E49BAB7CA1AC:4FB05E1515AB73A7 +02FE55778117F12A:5A6B612CC26CCE4A:49E95D6D4CA229BF +1D9D5C5018F728C2:5F4C038ED12B2E41:018310DC409B26D6 +305532286D6F295A:63FAC0D034D9F793:1C587F1C13924FEF + +# Tests the permutation +0000000000000000:88D55E54F54C97B4:1046913489980131 +0000000000000000:0C0CC00C83EA48FD:1007103489988020 +0000000000000000:83BC8EF3A6570183:10071034C8980120 +0000000000000000:DF725DCAD94EA2E9:1046103489988020 +0000000000000000:E652B53B550BE8B0:1086911519190101 +0000000000000000:AF527120C485CBB0:1086911519580101 +0000000000000000:0F04CE393DB926D5:5107B01519580101 +0000000000000000:C9F00FFC74079067:1007B01519190101 +0000000000000000:7CFD82A593252B4E:3107915498080101 +0000000000000000:CB49A2F9E91363E3:3107919498080101 +0000000000000000:00B588BE70D23F56:10079115B9080140 +0000000000000000:406A9A6AB43399AE:3107911598080140 +0000000000000000:6CB773611DCA9ADA:1007D01589980101 +0000000000000000:67FD21C17DBB5D70:9107911589980101 +0000000000000000:9592CB4110430787:9107D01589190101 +0000000000000000:A6B7FF68A318DDD3:1007D01598980120 +0000000000000000:4D102196C914CA16:1007940498190101 +0000000000000000:2DFA9F4573594965:0107910491190401 +0000000000000000:B46604816C0E0774:0107910491190101 +0000000000000000:6E7E6221A4F34E87:0107940491190401 +0000000000000000:AA85E74643233199:19079210981A0101 +0000000000000000:2E5A19DB4D1962D6:1007911998190801 +0000000000000000:23A866A809D30894:10079119981A0801 +0000000000000000:D812D961F017D320:1007921098190101 +0000000000000000:055605816E58608F:100791159819010B +0000000000000000:ABD88E8B1B7716F1:1004801598190101 +0000000000000000:537AC95BE69DA1E1:1004801598190102 +0000000000000000:AED0F6AE3C25CDD8:1004801598190108 +0000000000000000:B3E35A5EE53E7B8D:1002911598100104 +0000000000000000:61C79C71921A2EF8:1002911598190104 +0000000000000000:E2F5728F0995013C:1002911598100201 +0000000000000000:1AEAC39A61F0A464:1002911698100101 + # Vectors randomly generated using OpenSSL 0CEB1136A85AD37A:9CE3A1058A483F55:309A4B21A2067196 @@ -4693,6 +4768,8 @@ D6A025B07C037A6E1E0653E828FB9E3A3587CDDA5325D4DAA743D113D995D6AF E07306086FA442A42B107F7F355359DD972BF070C0C71FF5C37FA7C259C7E039 [IDEA] +7409000000000000:E18315C171B83765:ED1BCC9E9267925F3132BA3A8CF9B764 + D53FABBF94FF8B5F:1D0CB2AF1654820A:729A27ED8F5C3E8BAF16560D14C90B43 848F836780938169:D7E0468226D0FC56:729A27ED8F5C3E8BAF16560D14C90B43 819440CA2065D112:264A8BBA66959075:729A27ED8F5C3E8BAF16560D14C90B43 @@ -4720,6 +4797,86 @@ FAE6D2BEAA96826E0A141E28323C4650050A0F14191E2328050A0F14191E2328:\ 85DF52005608193D2F7DE750212FB7347B7314925DE59C097B7314925DE59C09:\ 00010002000300040005000600070008 +C309000000000000A02A000000000000B03D000000000000C942000000000000\ +2B4C000000000000A04E0000000000009857000000000000C860000000000000\ +0063000000000000F2660000000000008698000000000000729D000000000000\ +34A000000000000023A500000000000010AE00000000000025AE000000000000\ +30D600000000000064DB000000000000BCE1000000000000F6E7000000000000\ +4AEC00000000000080F9000000000000E0FE00000000000061FF000000000000:\ +9C3C4F44BB50DF7367DAD70E6FED04E0AEB0344116C6E41F66A1A304E822132D\ +8AFCC1727259D93DD6E742EAEF2FD8C03EAD7890DC4EFACBB8776F3439A3DB1B\ +55D47DC6BC4A43349BA9E85FE178CD1ADBDD4E9D19CA1E7659341251586E1386\ +4A8C4E93A2616A0C18890A622452AD9FD09CB1A9CDC83ABF2FCFA325FA011731\ +9C924852D426132D05DA82EEBC3C261A6036C6477FBE3F65C40B8B02C2F9D8C8\ +B3084034AB3873CF22F20759C145ECCE92CE6B557D6DB959DA0B8AD4E0DFBCEA:\ +F2022315280960F16FD09741D13F693A + +7CC254F81BE8E78D765A2E63339FC99A66320DB73158A35A255D051758E95ED4\ +ABB2CDC69BB454110E827441213DDC8770E93EA141E1FC673E017E97EADC6B96\ +8F385C2AECB03BFB32AF3C54EC18DB5C021AFE43FBFAAA3AFB29D1E6053C7C94\ +75D8BE6189F95CBBA8990F95B1EBF1B305EFF700E9A13AE5CA0BCBD0484764BD\ +1F231EA81C7B64C514735AC55E4B79633B706424119E09DCAAD4ACF21B10AF3B\ +33CDE3504847155CBB6F2219BA9B7DF50BE11A1C7F23F829F8A41B13B5CA4EE8\ +983238E0794D3D34BC5F4E77FACB6C05AC86212BAA1A55A2BE70B5733B045CD3\ +3694B3AFE2F0E49E4F321549FD824EA90870D4B28A2954489A0ABCD50E18A844\ +AC5BF38E4CD72D9B0942E506C433AFCDA3847F2DADD47647DE321CEC4AC430F6\ +2023856CFBB20704F4EC0BB920BA86C33E05F1ECD96733B79950A3E314D3D934\ +F75EA0F210A8F6059401BEB4BC4478FA4969E623D01ADA696A7E4C7E5125B348\ +84533A94FB319990325744EE9BBCE9E525CF08F5E9E25E5360AAD2B2D085FA54\ +D835E8D466826498D9A8877565705A8A3F62802944DE7CA5894E5759D351ADAC\ +869580EC17E485F18C0C66F17CC07CBB22FCE466DA610B63AF62BC83B4692F3A\ +FFAF271693AC071FB86D11342D8DEF4F89D4B66335C1C7E4248367D8ED9612EC\ +453902D8E50AF89D7709D1A596C1F41F95AA82CA6C49AE90CD1668BAAC7AA6F2\ +B4A8CA99B2C2372ACB08CF61C9C3805E6E0328DA4CD76A19EDD2D3994C798B00\ +22569AD418D1FEE4D9CD45A391C601FFC92AD91501432FEE150287617C13629E\ +69FC7281CD7165A63EAB49CF714BCE3A75A74F76EA7E64FF81EB61FDFEC39B67\ +BF0DE98C7E4E32BDF97C8C6AC75BA43C02F4B2ED7216ECF3014DF000108B67CF\ +99505B179F8ED4980A6103D1BCA70DBE9BBFAB0ED59801D6E5F2D6F67D3EC516\ +8E212E2DAF02C6B963C98A1F7097DE0C56891A2B211B01070DD8FD8B16C2A1A4\ +E3CFD292D2984B3561D555D16C33DDC2BCF7EDDE13EFE520C7E2ABDDA44D8188\ +1C531AEEEB66244C3B791EA8ACFB6A68F3584606472B260E0DD2EBB21F6C3A3B\ +C0542AABBA4EF8F6C7169E731108DB0460220AA74D31B55B03A00D220D475DCD\ +9B877856D5704C9C86EA0F98F2EB9C530DA7FA5AD8B0B5DB50C2FD5D095A2AA5\ +E2A3FBB71347549A316332234ECE765B7571B64D216B28712E25CF3780F9DC62\ +9CD719B01E6D4A4FD17C731F4AE97BC05A310D7B9C36EDCA5BBC02DBB5DE3D52\ +B65702D4C44C2495C897B5128030D2DB61E056FD1643C871FFCA4DB5A88A075E\ +E10933A655573B1DEEF02F6E20024981E2A07FF8E34769E311B698B9419F1822\ +A84BC8FDA2041A90F449FE154B48962DE81525CB5C8FAE6D45462786E53FA98D\ +8A718A2C75A4BC6AEEBA7F39021567EA2B8CB6871B64F561AB1CE7905B901EE5:\ +9C142A22EDF81444F47272B80A037C169E304393537CECE8003BD80F7B054406\ +3B4A141F9A99D3C6820BAD98BECD914804F389EB2A50E1E2CF22161FC78B9366\ +0E07E2686E70AC0715299C4796F3559FDA802E61CB4ABBF42BAE516BD09FA410\ +085A0A92C6F32A3797D19808D3B3D049B605852E970E5A1B8031D3DC34B5A273\ +F54ED35E21D780204F4B3C512596237153BE9FAF74A44E9A9DCBE96D628AA58B\ +1E3363A94DF540230B38A1ACA440432640E5387D92F1CC1A16F8628A4CB6229F\ +513AB926300668CF97B27643C9C9D0C3030D0CDFBBCB69C3DB199E5D392A97A5\ +1DE6C9881AE5612A69FA0EA026F2F254B929201AFB3AFC8D977C3ED6E12F0118\ +92037D0F49B0144E07A0F0556F0BAC9B3F829C233265439AF711E0B5DD6EC813\ +FD51281E8AA6F031B096C64EE8F03E041FE4DC6B5441141F2D4A308CE8EA77C6\ +483E3CF565EC49CF27A0B13F28D3C63AD7FB6B3A96579D30C9D65F7BA86E56DA\ +6D14AF3C7D170CB5BF5F21C70C1771354DA2850CFF8D9250273828C1FE60C4AC\ +086049404E3D63E04935F03B057B4783B13CF49757A8B5ABB3D2E37E54B881D2\ +36F7DF7FE80E4AE33E9125F54AA96D96BFB15607F0800B215CBF9BB0F7E29080\ +D8504E9BC1F78256593B9565E5AA5FA22032A47041B453D1B154A8D24CD59CF9\ +AA6A8E55363F3DF2B6307ABA5134D67B0DF0AE4FE77F23BF7DF8504FE9DC7F32\ +A8562E2DF585E639847DD624E55B0D0DCCDA72D0F1E072D82D4BC135DC5F7F91\ +30956D401FAB1456527FE087A436C1511CDFEA58202D200E1817E360E8400AAE\ +83B073A63596B033D7E83C6CAB7FDD7069C3B1718EAF60B937CD2458255E68FC\ +D9514FD14AA6E27EC76E75F95F0A678A0F64D49C1B9B8F8DA56DDB8CE640FF6E\ +7195F4A679165F9996F3DDF992E3CB4ED9E9084AFC0038E4BEFB467CC8170AF8\ +F004082BBCB137BBD45C124BE8CEDC89DD565A24830889CE4B9781FC18803BDA\ +1A0A4EB70DA35887B02F18CFF9329E2B7C31B0F5F0648E0508379B52C8FF91CE\ +F939A040A8C20F2F27ED65553680729A2181B3B3C4AA02BFF8DF0A9228A87BBF\ +52B48F473D0F9070C76E4DB6F09FFDFEB629BD0E1944B7016AF34187E2985AEA\ +E30D6480A58F649A0C858E1F1458388A9E822A306AC1AA7465882DE78F242EF7\ +B0CB45D68A057F00D8609587922C8FAD6F1A7FFA34BF2175FC516730A61CF82C\ +6F866C978CC292BCC1F91E6AF1785FCDAA9A43A01E6AEE91E222F8AF8C989F2A\ +4C50B7A1D45BC15E11E5E6E6EF720506B8DF564648BEBFE272C0A77D41295865\ +108150CDB3620970A37DB94F1CC35E434DC33434D99871F6141EB57C9E648AD1\ +BF70E2B7FCEB81EA871DD92F19C366EA532CA4A7BEF9242128B7ADDD308B58FF\ +F5594CB4156A03C6A6ED3F27E8DB20FB2F4208422B7E9E0A4E63A0122560CFBC:\ +67C6697351FF4AEC29CDBAABF2FBE346 + # Randomly generated by OpenSSL A1F4C5FC0AF894FB:1F88AD254A1653CB:69E2F555209FCA21ED36E0243F043537 55E31A38B2C91116:8D57CB7AFB401E55:BC0ED7C4A90FE4760B3D971F0F2589F6 diff --git a/configure.py b/configure.py index f5cd34336..123c91259 100755 --- a/configure.py +++ b/configure.py @@ -5,15 +5,16 @@ Configuration program for botan (http://botan.randombit.net/) (C) 2009-2011 Jack Lloyd Distributed under the terms of the Botan license -Tested with - CPython 2.5, 2.6, 2.7 - OK - Jython 2.5 - Target detection does not work (use --os and --cpu) +Tested with CPython 2.6, 2.7, 3.1 and PyPy 1.5 - CPython 2.4 and earlier are not supported +Python 2.5 works if you change the exception catching syntax: + perl -pi -e 's/except (.*) as (.*):/except $1, $2:/g' configure.py - Use the 2to3 script to use with Python 3 +Jython - Target detection does not work (use --os and --cpu) - Has not been tested with IronPython or PyPy +CPython 2.4 and earlier are not supported + +Has not been tested with IronPython """ import sys @@ -40,6 +41,25 @@ import botan_version def flatten(l): return sum(l, []) +def get_vc_revision(): + try: + mtn = subprocess.Popen(['mtn', 'automate', 'heads'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + (stdout, stderr) = mtn.communicate() + + if(stderr != ''): + logging.debug('Error getting rev from monotone - %s' % (stderr)) + return 'unknown' + + logging.debug('Monotone reported revision ' + stdout.strip()) + + return 'mtn:' + stdout.strip() + except OSError as e: + logging.debug('Error getting rev from monotone - %s' % (e[1])) + return 'unknown' + class BuildConfigurationInformation(object): """ @@ -48,9 +68,11 @@ class BuildConfigurationInformation(object): version_major = botan_version.release_major version_minor = botan_version.release_minor version_patch = botan_version.release_patch + version_so_rev = botan_version.release_so_abi_rev version_datestamp = botan_version.release_datestamp + version_vc_rev = botan_version.release_vc_rev version_string = '%d.%d.%d' % (version_major, version_minor, version_patch) """ @@ -58,6 +80,9 @@ class BuildConfigurationInformation(object): """ def __init__(self, options, modules): + if self.version_vc_rev is None: + self.version_vc_rev = get_vc_revision() + self.build_dir = os.path.join(options.with_build_dir, 'build') self.checkobj_dir = os.path.join(self.build_dir, 'checks') @@ -76,9 +101,17 @@ class BuildConfigurationInformation(object): self.internal_include_dir = os.path.join(self.botan_include_dir, 'internal') self.sources = sorted(flatten([mod.sources() for mod in modules])) - self.public_headers = sorted(flatten([m.public_headers() for m in modules])) self.internal_headers = sorted(flatten([m.internal_headers() for m in modules])) + if options.via_amalgamation: + self.build_sources = ['botan_all.cpp'] + self.build_internal_headers = [] + else: + self.build_sources = self.sources + self.build_internal_headers = self.internal_headers + + self.public_headers = sorted(flatten([m.public_headers() for m in modules])) + checks_dir = os.path.join(options.base_dir, 'checks') self.check_sources = sorted( @@ -124,6 +157,10 @@ class BuildConfigurationInformation(object): return 'botan-%d.%d.pc' % (self.version_major, self.version_minor) + def config_shell_script(self): + return 'botan-config-%d.%d' % (self.version_major, + self.version_minor) + def username(self): return getpass.getuser() @@ -149,12 +186,19 @@ def process_command_line(args): target_group = optparse.OptionGroup(parser, 'Target options') - target_group.add_option('--cc', dest='compiler', - help='set the desired build compiler') - target_group.add_option('--os', - help='set the target operating system') target_group.add_option('--cpu', help='set the target processor type/model') + + target_group.add_option('--os', + help='set the target operating system') + + target_group.add_option('--cc', dest='compiler', + help='set the desired build compiler') + + target_group.add_option('--cc-bin', dest='compiler_binary', + metavar='BINARY', + help='set the name of the compiler binary') + target_group.add_option('--with-endian', metavar='ORDER', default=None, help='override guess of CPU byte order') @@ -204,10 +248,18 @@ def process_command_line(args): build_group.add_option('--disable-debug', dest='debug_build', action='store_false', help=optparse.SUPPRESS_HELP) + build_group.add_option('--no-optimizations', dest='no_optimizations', + action='store_true', default=False, + help=optparse.SUPPRESS_HELP) + build_group.add_option('--gen-amalgamation', dest='gen_amalgamation', default=False, action='store_true', help='generate amalgamation files') + build_group.add_option('--via-amalgamation', dest='via_amalgamation', + default=False, action='store_true', + help='build via amalgamation') + build_group.add_option('--with-tr1-implementation', metavar='WHICH', dest='with_tr1', default=None, help='enable TR1 (choices: none, system, boost)') @@ -234,6 +286,12 @@ def process_command_line(args): build_group.add_option('--without-sphinx', action='store_false', dest='with_sphinx', help=optparse.SUPPRESS_HELP) + build_group.add_option('--with-visibility', action='store_true', + default=None, help=optparse.SUPPRESS_HELP) + + build_group.add_option('--without-visibility', action='store_false', + dest='with_visibility', help=optparse.SUPPRESS_HELP) + build_group.add_option('--with-doxygen', action='store_true', default=False, help='Use Doxygen to generate HTML API docs') @@ -453,7 +511,13 @@ def lex_me_harder(infofile, to_obj, allowed_groups, name_val_pairs): lexer.lineno) elif token in name_val_pairs.keys(): - to_obj.__dict__[token] = lexer.get_token() + next_val = lexer.get_token() + + if type(to_obj.__dict__[token]) is list: + to_obj.__dict__[token].append(next_val) + else: + to_obj.__dict__[token] = next_val + else: # No match -> error raise LexerError('Bad token "%s"' % (token), lexer.lineno) @@ -475,7 +539,7 @@ class ModuleInfo(object): 'comment'], { 'load_on': 'auto', - 'define': None, + 'define': [], 'uses_tr1': 'false', 'need_isa': None, 'mp_bits': 0 }) @@ -527,8 +591,9 @@ class ModuleInfo(object): self.uses_tr1 = (True if self.uses_tr1 == 'yes' else False) if self.comment != []: - logging.info('Module comment for ' + self.basename + ' - ' + - ' '.join(self.comment)) + self.comment = ' '.join(self.comment) + else: + self.comment = None def sources(self): return self.source @@ -539,6 +604,9 @@ class ModuleInfo(object): def internal_headers(self): return self.header_internal + def defines(self): + return ['HAS_' + d for d in self.define] + def compatible_cpu(self, archinfo, options): arch_name = archinfo.basename @@ -696,7 +764,8 @@ class CompilerInfo(object): 'lang_flags': '', 'warning_flags': '', 'maintainer_warning_flags': '', - 'dll_import_flags': '', + 'visibility_build_flags': '', + 'visibility_attribute': '', 'ar_command': None, 'makefile_style': '', 'has_tr1': False, @@ -724,6 +793,23 @@ class CompilerInfo(object): del self.mach_opt """ + Return the shared library build flags, if any + """ + def gen_shared_flags(self, options): + def flag_builder(): + if options.build_shared_lib: + yield self.shared_flags + if options.with_visibility: + yield self.visibility_build_flags + + return ' '.join(list(flag_builder())) + + def gen_visibility_attribute(self, options): + if options.build_shared_lib and options.with_visibility: + return self.visibility_attribute + return '' + + """ Return the machine specific ABI flags """ def mach_abi_link_flags(self, osname, arch, submodel, debug_p): @@ -763,13 +849,18 @@ class CompilerInfo(object): """ Return the flags for LIB_OPT """ - def library_opt_flags(self, debug_build): - flags = self.lib_opt_flags - if debug_build and self.debug_flags != '': - flags += ' ' + self.debug_flags - if not debug_build and self.no_debug_flags != '': - flags += ' ' + self.no_debug_flags - return flags + def library_opt_flags(self, options): + def gen_flags(): + if options.debug_build: + yield self.debug_flags + + if not options.no_optimizations: + yield self.lib_opt_flags + + if not options.debug_build: + yield self.no_debug_flags + + return (' '.join(gen_flags())).strip() """ Return the command needed to link a shared object @@ -838,19 +929,30 @@ def fixup_proc_name(proc): def canon_processor(archinfo, proc): proc = fixup_proc_name(proc) + # First, try to search for an exact match for ainfo in archinfo.values(): if ainfo.basename == proc or proc in ainfo.aliases: return (ainfo.basename, ainfo.basename) - else: - for (match,submodel) in ainfo.all_submodels(): - if re.search(match, proc) != None: - return (ainfo.basename, submodel) + + for (match,submodel) in ainfo.all_submodels(): + if proc == submodel or proc == match: + return (ainfo.basename, submodel) + + logging.debug('Could not find an exact match for CPU "%s"' % (proc)) + + # Now, try searching via regex match + for ainfo in archinfo.values(): + for (match,submodel) in ainfo.all_submodels(): + if re.search(match, proc) != None: + logging.debug('Possible match "%s" with "%s" (%s)' % ( + proc, match, submodel)) + return (ainfo.basename, submodel) logging.debug('Known CPU names: ' + ' '.join( - sorted(sum([[ainfo.basename] + \ - ainfo.aliases + \ - [x for (x,_) in ainfo.all_submodels()] - for ainfo in archinfo.values()], [])))) + sorted(flatten([[ainfo.basename] + \ + ainfo.aliases + \ + [x for (x,_) in ainfo.all_submodels()] + for ainfo in archinfo.values()])))) raise Exception('Unknown or unidentifiable processor "%s"' % (proc)) @@ -891,7 +993,7 @@ def process_template(template_file, variables): try: template = PercentSignTemplate(slurp_file(template_file)) return template.substitute(variables) - except KeyError, e: + except KeyError as e: raise Exception('Unbound var %s in template %s' % (e, template_file)) """ @@ -920,13 +1022,21 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): def objectfile_list(sources, obj_dir): for src in sources: - basename = os.path.basename(src) + (dir,file) = os.path.split(os.path.normpath(src)) + + if dir.startswith('src'): + parts = dir.split(os.sep)[1:] + if file == parts[-1] + '.cpp': + name = '_'.join(dir.split(os.sep)[1:]) + '.cpp' + else: + name = '_'.join(dir.split(os.sep)[1:]) + '_' + file + else: + name = file for src_suffix in ['.cpp', '.S']: - basename = basename.replace(src_suffix, - '.' + osinfo.obj_suffix) + name = name.replace(src_suffix, '.' + osinfo.obj_suffix) - yield os.path.join(obj_dir, basename) + yield os.path.join(obj_dir, name) def choose_mp_bits(): @@ -965,11 +1075,6 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): return os.path.join(options.with_build_dir, path) return path - def only_if_shared(option): - if options.build_shared_lib: - return option - return '' - def warning_flags(normal_flags, maintainer_flags, maintainer_mode): @@ -978,10 +1083,12 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): return normal_flags return { - 'version_major': build_config.version_major, - 'version_minor': build_config.version_minor, - 'version_patch': build_config.version_patch, - 'version': build_config.version_string, + 'version_major': build_config.version_major, + 'version_minor': build_config.version_minor, + 'version_patch': build_config.version_patch, + 'version_vc_rev': build_config.version_vc_rev, + 'so_abi_rev': build_config.version_so_rev, + 'version': build_config.version_string, 'distribution_info': options.distribution_info, @@ -1014,26 +1121,26 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'mp_bits': choose_mp_bits(), - 'cc': cc.binary_name + cc.mach_abi_link_flags( - options.os, options.arch, options.cpu, options.debug_build), + 'cc': (options.compiler_binary or cc.binary_name) + + cc.mach_abi_link_flags(options.os, options.arch, + options.cpu, options.debug_build), - 'lib_opt': cc.library_opt_flags(options.debug_build), + 'lib_opt': cc.library_opt_flags(options), 'mach_opt': cc.mach_opts(options.arch, options.cpu), - 'check_opt': cc.check_opt_flags, + 'check_opt': '' if options.no_optimizations else cc.check_opt_flags, 'lang_flags': cc.lang_flags + options.extra_flags, 'warn_flags': warning_flags(cc.warning_flags, cc.maintainer_warning_flags, options.maintainer_mode), - 'shared_flags': only_if_shared(cc.shared_flags), - 'dll_import_flags': only_if_shared(cc.dll_import_flags), + 'shared_flags': cc.gen_shared_flags(options), + 'visibility_attribute': cc.gen_visibility_attribute(options), 'so_link': cc.so_link_command_for(osinfo.basename), 'link_to': ' '.join([cc.add_lib_option + lib for lib in link_to()]), - 'module_defines': make_cpp_macros( - sorted(['HAS_' + m.define for m in modules if m.define])), + 'module_defines': make_cpp_macros(sorted(flatten([m.defines() for m in modules]))), 'target_os_defines': make_cpp_macros(osinfo.defines()), @@ -1045,7 +1152,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'include_files': makefile_list(build_config.public_headers), 'lib_objs': makefile_list( - objectfile_list(build_config.sources, + objectfile_list(build_config.build_sources, build_config.libobj_dir)), 'check_objs': makefile_list( @@ -1053,7 +1160,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): build_config.checkobj_dir)), 'lib_build_cmds': '\n'.join( - build_commands(build_config.sources, + build_commands(build_config.build_sources, build_config.libobj_dir, 'LIB')), 'check_build_cmds': '\n'.join( @@ -1082,7 +1189,9 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'so_suffix': osinfo.so_suffix, 'botan_config': prefix_with_build_dir( - os.path.join(build_config.build_dir, 'botan-config')), + os.path.join(build_config.build_dir, + build_config.config_shell_script())), + 'botan_pkgconfig': prefix_with_build_dir( os.path.join(build_config.build_dir, build_config.pkg_config_file())), @@ -1196,6 +1305,14 @@ def choose_modules_to_use(modules, archinfo, options): logging.info('Skipping, %s - %s' % ( reason, ' '.join(disabled_mods))) + for mod in sorted(to_load): + if mod.startswith('mp_'): + logging.info('Using MP module ' + mod) + if mod.startswith('simd_') and mod != 'simd_engine': + logging.info('Using SIMD module ' + mod) + if modules[mod].comment: + logging.info('%s: %s' % (mod, modules[mod].comment)) + logging.debug('Loading modules %s', ' '.join(sorted(to_load))) return [modules[mod] for mod in to_load] @@ -1316,14 +1433,14 @@ def setup_build(build_config, options, template_vars): try: if options.clean_build_tree: shutil.rmtree(build_config.build_dir) - except OSError, e: + except OSError as e: if e.errno != errno.ENOENT: logging.error('Problem while removing build dir: %s' % (e)) for dir in build_config.build_dirs: try: os.makedirs(dir) - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: logging.error('Error while creating "%s": %s' % (dir, e)) @@ -1343,7 +1460,7 @@ def setup_build(build_config, options, template_vars): if options.os != 'windows': yield (options.build_data, 'botan.pc.in', build_config.pkg_config_file()) - yield (options.build_data, 'botan-config.in', 'botan-config') + yield (options.build_data, 'botan-config.in', build_config.config_shell_script()) if options.os == 'windows': yield (options.build_data, 'innosetup.in', 'botan.iss') @@ -1374,7 +1491,7 @@ def setup_build(build_config, options, template_vars): for header_file in header_list: try: portable_symlink(header_file, dir, link_method) - except OSError, e: + except OSError as e: if e.errno != errno.EEXIST: logging.error('Error linking %s into %s: %s' % ( header_file, dir, e)) @@ -1382,7 +1499,7 @@ def setup_build(build_config, options, template_vars): link_headers(build_config.public_headers, 'public', build_config.botan_include_dir) - link_headers(build_config.internal_headers, 'internal', + link_headers(build_config.build_internal_headers, 'internal', build_config.internal_include_dir) """ @@ -1459,12 +1576,16 @@ def generate_amalgamation(build_config): else: match = std_include.search(line) - if match: + if match and match.group(1) != 'functional': self.all_std_includes.add(match.group(1)) else: yield line - botan_all_h = open('botan_all.h', 'w') + amalg_basename = 'botan_all' + + header_name = '%s.h' % (amalg_basename) + + botan_h = open(header_name, 'w') pub_header_amalag = Amalgamation_Generator(build_config.public_headers) @@ -1476,31 +1597,30 @@ def generate_amalgamation(build_config): */ """ % (build_config.version_string) - botan_all_h.write(amalg_header) + botan_h.write(amalg_header) - botan_all_h.write(""" + botan_h.write(""" #ifndef BOTAN_AMALGAMATION_H__ #define BOTAN_AMALGAMATION_H__ """) - botan_all_h.write(pub_header_amalag.header_includes) - botan_all_h.write(pub_header_amalag.contents) - botan_all_h.write("\n#endif\n") + botan_h.write(pub_header_amalag.header_includes) + botan_h.write(pub_header_amalag.contents) + botan_h.write("\n#endif\n") internal_header_amalag = Amalgamation_Generator( [s for s in build_config.internal_headers if s.find('asm_macr_') == -1]) - botan_all_cpp = open('botan_all.cpp', 'w') - - botan_all_cpp.write(amalg_header) + botan_cpp = open('%s.cpp' % (amalg_basename), 'w') - botan_all_cpp.write('#include "botan_all.h"\n') + botan_cpp.write(amalg_header) - botan_all_cpp.write(internal_header_amalag.header_includes) - botan_all_cpp.write(internal_header_amalag.contents) + botan_cpp.write('\n#include "%s"\n' % (header_name)) + botan_cpp.write(internal_header_amalag.header_includes) + botan_cpp.write(internal_header_amalag.contents) for src in build_config.sources: if src.endswith('.S'): @@ -1511,7 +1631,7 @@ def generate_amalgamation(build_config): if botan_include.search(line): continue else: - botan_all_cpp.write(line) + botan_cpp.write(line) """ Test for the existence of a program @@ -1543,6 +1663,9 @@ def main(argv = None): if argv is None: argv = sys.argv + logging.basicConfig(stream = sys.stdout, + format = '%(levelname) 7s: %(message)s') + options = process_command_line(argv[1:]) def log_level(): @@ -1552,9 +1675,7 @@ def main(argv = None): return logging.WARNING return logging.INFO - logging.basicConfig(stream = sys.stdout, - format = '%(levelname) 7s: %(message)s', - level = log_level()) + logging.getLogger().setLevel(log_level()) logging.debug('%s invoked with options "%s"' % ( argv[0], ' '.join(argv[1:]))) @@ -1573,28 +1694,29 @@ def main(argv = None): (modules, archinfo, ccinfo, osinfo) = load_info_files(options) - if options.os is None: - options.os = platform.system().lower() - - if re.match('^cygwin_.*', options.os): - logging.debug("Converting '%s' to 'cygwin'", options.os) - options.os = 'cygwin' - - logging.info('Guessing target OS is %s (--os to set)' % (options.os)) - if options.compiler is None: if options.os == 'windows': - if have_program('cl'): - options.compiler = 'msvc' - elif have_program('g++'): + if have_program('g++') and not have_program('cl'): options.compiler = 'gcc' else: options.compiler = 'msvc' else: options.compiler = 'gcc' - logging.info('Guessing to use compiler %s (--cc to set)' % ( + logging.info('Guessing to use compiler %s (use --cc to set)' % ( options.compiler)) + if options.os is None: + options.os = platform.system().lower() + + if re.match('^cygwin_.*', options.os): + logging.debug("Converting '%s' to 'cygwin'", options.os) + options.os = 'cygwin' + + if options.os == 'windows' and options.compiler == 'gcc': + logging.warning('Detected GCC on Windows; use --os=cygwin or --os=mingw?') + + logging.info('Guessing target OS is %s (use --os to set)' % (options.os)) + if options.compiler not in ccinfo: raise Exception('Unknown compiler "%s"; available options: %s' % ( options.compiler, ' '.join(sorted(ccinfo.keys())))) @@ -1615,7 +1737,7 @@ def main(argv = None): if options.cpu is None: (options.arch, options.cpu) = guess_processor(archinfo) - logging.info('Guessing target processor is a %s/%s (--cpu to set)' % ( + logging.info('Guessing target processor is a %s/%s (use --cpu to set)' % ( options.arch, options.cpu)) else: cpu_from_user = options.cpu @@ -1626,54 +1748,84 @@ def main(argv = None): logging.info('Target is %s-%s-%s-%s' % ( options.compiler, options.os, options.arch, options.cpu)) + cc = ccinfo[options.compiler] + # Kind of a hack... options.extra_flags = '' if options.compiler == 'gcc': + def get_gcc_version(gcc_bin): + try: + subproc_result = subprocess.Popen( + gcc_bin.split(' ') + ['-dumpversion'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate() + + gcc_version = ''.join(map(str, subproc_result)).strip() + + logging.info('Detected gcc version %s' % (gcc_version)) + return gcc_version + except OSError: + logging.warning('Could not execute %s for version check' % (gcc_bin)) + return None + def is_64bit_arch(arch): if arch.endswith('64') or arch in ['alpha', 's390x']: return True return False - if not is_64bit_arch(options.arch) and not options.dumb_gcc: - try: - matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])' + gcc_version = get_gcc_version(options.compiler_binary or cc.binary_name) - gcc_version = ''.join(subprocess.Popen( - ['g++', '-dumpversion'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE).communicate()).strip() + if gcc_version: - logging.info('Detected GCC version %s' % (gcc_version)) + if not is_64bit_arch(options.arch) and not options.dumb_gcc: + matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])' if re.search(matching_version, gcc_version): options.dumb_gcc = True - except OSError: - logging.warning('Could not execute GCC for version check') + + versions_without_tr1 = '(4\.0\.)|(3\.[0-4]\.)|(2\.95\.[0-4])' + + if options.with_tr1 == None and \ + re.search(versions_without_tr1, gcc_version): + logging.info('Disabling TR1 support for this gcc, too old') + options.with_tr1 = 'none' + + versions_without_visibility = '(3\.[0-4]\.)|(2\.95\.[0-4])' + if options.with_visibility == None and \ + re.search(versions_without_visibility, gcc_version): + logging.info('Disabling DSO visibility support for this gcc, too old') + options.with_visibility = False if options.dumb_gcc is True: logging.info('Setting -fpermissive to work around gcc bug') options.extra_flags = ' -fpermissive' + if options.with_visibility is None: + options.with_visibility = True + if options.with_tr1 == None: - options.with_tr1 = ('system' if ccinfo[options.compiler].has_tr1 else 'none') + if cc.has_tr1: + logging.info('Assuming %s has TR1 (use --with-tr1=none to disable)' % ( + options.compiler)) + options.with_tr1 = 'system' + else: + options.with_tr1 = 'none' if options.with_sphinx is None: if have_program('sphinx-build'): - logging.info('Found sphinx-build, will enable; ' + - 'use --without-sphinx to disable') + logging.info('Found sphinx-build, will use it ' + + '(use --without-sphinx to disable)') options.with_sphinx = True + if options.via_amalgamation: + options.gen_amalgamation = True + if options.gen_amalgamation: if options.asm_ok: logging.info('Disabling assembly code, cannot use in amalgamation') options.asm_ok = False - for mod in ['sha1_sse2', 'serpent_simd']: - if mod not in options.disabled_modules: - logging.info('Disabling %s, cannot use in amalgamation' % (mod)) - options.disabled_modules.append(mod) - modules_to_use = choose_modules_to_use(modules, archinfo[options.arch], options) @@ -1689,7 +1841,7 @@ def main(argv = None): template_vars = create_template_vars(build_config, options, modules_to_use, - ccinfo[options.compiler], + cc, archinfo[options.arch], osinfo[options.os]) @@ -1705,7 +1857,7 @@ def main(argv = None): if __name__ == '__main__': try: main() - except Exception, e: + except Exception as e: logging.error(str(e)) #import traceback #traceback.print_exc(file=sys.stderr) diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html new file mode 100644 index 000000000..c907c7597 --- /dev/null +++ b/doc/_templates/layout.html @@ -0,0 +1,9 @@ +{% extends "!layout.html" %} + +{% block header %} + <div class="header-wrapper"> + <div class="header"> + <h1>{{ shorttitle|e }}</h1> + </div> + </div> +{% endblock %} diff --git a/doc/algos.txt b/doc/algos.txt index bc1477ee7..119b81a7f 100644 --- a/doc/algos.txt +++ b/doc/algos.txt @@ -12,39 +12,33 @@ primitives, including: * Public key cryptography - * Encryption algorithms RSA, ElGamal, DLIES (padding schemes OAEP, - PKCS #1 v1.5) - * Signature algorithms RSA, DSA, ECDSA, GOST 34.10-2001, - Nyberg-Rueppel, Rabin-Williams (padding schemes PSS, PKCS #1 v1.5, - X9.31) - * Key agreement techniques Diffie-Hellman and ECDH + * Encryption algorithms RSA, ElGamal, DLIES (padding schemes OAEP, + PKCS #1 v1.5) + * Signature algorithms RSA, DSA, ECDSA, GOST 34.10-2001, + Nyberg-Rueppel, Rabin-Williams (padding schemes PSS, PKCS #1 v1.5, + X9.31) + * Key agreement techniques Diffie-Hellman and ECDH * Hash functions - * NIST hashes: SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 - - * RIPE hashes: RIPEMD-160 and RIPEMD-128 - - * SHA-3 candidates Skein-512, Keccak, and Blue Midnight Wish-512 - - * Other common hash functions Whirlpool and Tiger - - * National standard hashes HAS-160 and GOST 34.11 - - * Obsolete or insecure hashes MD5, MD4, MD2 - - * Non-cryptographic checksums Adler32, CRC24, CRC32 + * NIST hashes: SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 + * RIPE hashes: RIPEMD-160 and RIPEMD-128 + * SHA-3 candidates Skein-512, Keccak, and Blue Midnight Wish-512 + * Other common hash functions Whirlpool and Tiger + * National standard hashes HAS-160 and GOST 34.11 + * Obsolete or insecure hashes MD5, MD4, MD2 + * Non-cryptographic checksums Adler32, CRC24, CRC32 * Block ciphers - * AES (Rijndael) and AES candidates Serpent, Twofish, MARS, CAST-256, RC6 - * DES, and variants 3DES and DESX - * National/telecom block ciphers SEED, KASUMI, MISTY1, GOST 28147, Skipjack - * Other block ciphers including Blowfish, CAST-128, IDEA, Noekeon, - TEA, XTEA, RC2, RC5, SAFER-SK, and Square - * Block cipher constructions Luby-Rackoff and Lion - * Block cipher modes ECB, CBC, CBC/CTS, CFB, OFB, CTR, XTS and - authenticated cipher mode EAX + * AES (Rijndael) and AES candidates Serpent, Twofish, MARS, CAST-256, RC6 + * DES, and variants 3DES and DESX + * National/telecom block ciphers SEED, KASUMI, MISTY1, GOST 28147, Skipjack + * Other block ciphers including Blowfish, CAST-128, IDEA, Noekeon, + TEA, XTEA, RC2, RC5, SAFER-SK, and Square + * Block cipher constructions Luby-Rackoff and Lion + * Block cipher modes ECB, CBC, CBC/CTS, CFB, OFB, CTR, XTS and + authenticated cipher mode EAX * Stream ciphers ARC4, Salsa20/XSalsa20, Turing, and WiderWake4+1 @@ -53,17 +47,17 @@ primitives, including: * Public Key Infrastructure - * X.509 certificates (including generating new self-signed and CA - certs) and CRLs - * Certificate path validation - * PKCS #10 certificate requests (creation and certificate issue) + * X.509 certificates (including generating new self-signed and CA + certs) and CRLs + * Certificate path validation + * PKCS #10 certificate requests (creation and certificate issue) * Other cryptographic utility functions including - * Key derivation functions for passwords: PBKDF1 (PKCS #5 v1.5), - PBKDF2 (PKCS #5 v2.0), OpenPGP S2K (RFC 2440) - * General key derivation functions KDF1 and KDF2 from IEEE 1363 - * PRFs from ANSI X9.42, SSL v3.0, TLS v1.0 + * Key derivation functions for passwords: PBKDF1 (PKCS #5 v1.5), + PBKDF2 (PKCS #5 v2.0), OpenPGP S2K (RFC 2440) + * General key derivation functions KDF1 and KDF2 from IEEE 1363 + * PRFs from ANSI X9.42, SSL v3.0, TLS v1.0 Recommended Algorithms --------------------------------- diff --git a/doc/build_log.txt b/doc/build_log.txt index de6197389..2e92a6f90 100644 --- a/doc/build_log.txt +++ b/doc/build_log.txt @@ -14,6 +14,11 @@ Debian reports the build results for 1.8 on `a number of platforms =========== ======= =================== ======================== ============================ ======== Date Version OS CPU Compiler Results =========== ======= =================== ======================== ============================ ======== +2011-05-09 1.9.17 Debian 6.0 Intel Atom D510 GCC 4.4.5 OK +2010-05-09 1.9.17 Gentoo 10.0 PowerPC G5 GCC 4.4.5 OK +2011-05-02 1.9.17 FreeBSD 8.2 x86-64 GCC 4.2.1 OK +2011-04-25 1.9.16 Gentoo 10.0 Intel Core i7-860 Clang 2.9 Miscompiles SSE2 IDEA +2011-04-23 1.9.16 Gentoo 10.0 Intel Core i7-860 Sun C++ 5.10 OK 2011-04-22 1.9.16 Gentoo 10.0 Intel Core i7-860 Intel C++ 11.1 OK 2011-04-15 1.9.16 Haiku R1-alpha2 x86 GCC 4.3.3 OK 2011-04-15 1.9.16 Haiku R1-alpha2 x86 GCC 2.95.3 Can't compile diff --git a/doc/building.txt b/doc/building.txt index 56beef43e..e16531de4 100644 --- a/doc/building.txt +++ b/doc/building.txt @@ -60,10 +60,11 @@ we might see lines like:: INFO: Skipping, incompatible OS - beos_stats cryptoapi_rng win32_crit_section win32_stats INFO: Skipping, incompatible compiler - mp_msvc64 mp_x86_32_msvc -The ones that are 'loaded on request only' have to be explicitly asked -for, because they rely on third party libraries which your system -might not have. For instance to enable zlib support, add -``--with-zlib`` to your invocation of ``configure.py``. +The ones that are skipped because they are 'by request only' have to +be explicitly asked for, because they rely on third party libraries +which your system might not have or that you might not want the +resulting binary to depend on. For instance to enable zlib support, +add ``--with-zlib`` to your invocation of ``configure.py``. You can control which algorithms and modules are built using the options ``--enable-modules=MODS`` and ``--disable-modules=MODS``, for @@ -136,6 +137,26 @@ self-test program:: $ install_name_tool -change $(otool -X -D libbotan-$VERSION.dylib) \ $PWD/libbotan-$VERSION.dylib check +Building Universal Binaries +&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + +To build a universal binary for OS X, some simple modifications are +required. First, create a CPU type for the target universalbinary, +one that doesn't specify any special handlers. This is done by +creating an empty file in src/build-data/arch:: + + $ touch src/build-data/arch/universalbinary.txt + +and then adding a special target for it in gcc, by adding the line:: + + universalbinary -> "-force_cpusubtype_ALL -mmacosx-version-min=10.4 -arch i386 -arch ppc" + +in the section marked `<mach_abi_linking>` in +`src/build-data/cc/gcc.txt`. Then configure with:: + + $ ./configure.py --cpu=universalbinary [other options here] + + On MS Windows ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -168,26 +189,46 @@ compiler to look for both include files and library files in place where they will be in the default compiler search paths (consult your documentation and/or local expert for details). +Other Build-Related Tasks +---------------------------------------- + +.. _building_docs: + +Building The Documentation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are two documentation options available, Sphinx and Doxygen. +Sphinx will be used if ``sphinx-build`` is detected in the PATH, or if +``--with-sphinx`` is used at configure time. Doxygen is only enabled +if ``--with-doxygen`` is used. Both are generated by the makefile +target ``docs``. + + .. _amalgamation: The Amalgamation Build ----------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can also configure Botan to be built using only a single source file; this is quite convenient if you plan to embed the library into -another application. To do so, run ``configure.py`` with -whatever arguments you would ordinarily use, along with the option -``--gen-amalgamation``. This will create two (rather large) -files, ``botan_all.h`` and ``botan_all.cpp``. +another application. To do so, run ``configure.py`` with whatever +arguments you would ordinarily use, along with the option +``--gen-amalgamation``. This will create two (rather large) files, +``botan_all.h`` and ``botan_all.cpp``. Whenever you would have included a botan header, you can then include -``botan_all.h``, and include ``botan_all.cpp`` along -with the rest of the source files in your build. If you want to be -able to easily switch between amalgamated and non-amalgamated versions -(for instance to take advantage of prepackaged versions of botan on -operating systems that support it), you can instead ignore -``botan_all.h`` and use the headers from -``build/include`` as normal. +``botan_all.h``, and include ``botan_all.cpp`` along with the rest of +the source files in your build. If you want to be able to easily +switch between amalgamated and non-amalgamated versions (for instance +to take advantage of prepackaged versions of botan on operating +systems that support it), you can instead ignore ``botan_all.h`` and +use the headers from ``build/include`` as normal. + +You can also build the library as normal but using the amalgamation +instead of the individual source files using ``--via-amalgamation``. +This is essentially a very simple form of link time optimization; +because the entire library source is visible to the compiler, it has +more opportunities for interprocedural optimizations. Modules Relying on Third Party Libraries ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,13 +247,14 @@ enabled at build time; these include: and decompression. Requires the zlib development libraries to be installed. - - ``--with-gnump`` adds an alternative engine for public key cryptography - that uses the GNU MP library. GNU MP 4.1 or later is required. + - ``--with-gnump`` adds an alternative engine for public key + cryptography that uses the GNU MP library. GNU MP 4.1 or later is + required. - ``--with-openssl`` adds an engine that uses OpenSSL for some public key operations and ciphers/hashes. OpenSSL 0.9.7 or later is - required. Note that (unlike GNU MP) OpenSSL's versions are not - always faster than the versions built into botan. + required. Note that OpenSSL's versions are not always faster than + the versions built into botan. Multiple Builds ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +263,6 @@ It may be useful to run multiple builds with different configurations. Specify ``--build-dir=<dir>`` to set up a build environment in a different directory. - .. _configure_with_python3: Configuring the Build With Python 3.1 @@ -382,8 +423,8 @@ against is the same one you used to run ``configure.py``. To install the module, use the ``install`` target. -Examples of using the Python module can be seen in -``doc/examples/python`` +See :doc:`Python Bindings <python>` for more information about the +binding. Building the Perl XS wrappers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/conf.py b/doc/conf.py index 1a5dfe198..65f40314a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -31,6 +31,24 @@ import botan_version # If your documentation needs a minimal Sphinx version, state it here. needs_sphinx = '1.0' +""" +Assert that we are running under Sphinx 1.0.7 or later. Earlier +versions have bugs in the C++ domain that cause crashes. And +needs_sphinx only allows us to assert needing a particular major/minor +version. +""" +def check_sphinx_version(): + import sphinx + + version = map(int, sphinx.__version__.split('.')) + if version[0] == 1 and version[1] == 0 and version[2] < 7: + # Exit rather than throwing to avoid a confusing backtrace + print "This Sphinx is too old - upgrade to at least 1.0.7" + import sys + sys.exit(1) + +check_sphinx_version() + # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] @@ -103,12 +121,18 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = 'agogo' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +html_theme_options = { + 'linkcolor': 'blue', + 'headerlinkcolor': 'blue', + 'headercolor1': 'darkblue', + 'headercolor2': 'darkblue', + 'textalign': 'left' + } # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] diff --git a/doc/contents.txt b/doc/contents.txt index 023fa2b1c..dd600d587 100644 --- a/doc/contents.txt +++ b/doc/contents.txt @@ -5,7 +5,8 @@ Contents .. toctree:: :maxdepth: 2 - welcome + index + reading building firststep filters @@ -20,10 +21,12 @@ Contents passhash rng fpe + python .. toctree:: :hidden: + log license credits faq @@ -32,7 +35,6 @@ Contents download pgpkey algos - log build_log Indices and tables diff --git a/doc/download.txt b/doc/download.txt index b6229cfd6..b8d3e75b3 100644 --- a/doc/download.txt +++ b/doc/download.txt @@ -13,51 +13,53 @@ Unsure which release you want? Check the :ref:`FAQ <devel_vs_stable>`. If you are viewing this documentation offline, a more recent release `may be available <http://botan.randombit.net/download.html>`_ -Current Stable Release +Current Stable Release (1.10) ---------------------------------------- -The current stable release is `1.8.11 -<http://botan.randombit.net/news/releases/1_8_11.html>`_ which was -released on 2010-11-02. +The current stable release is `1.10.1 +<http://botan.randombit.net/news/releases/1_10_1.html>`_ which was +released on 2011-07-11. Sources: -`1.8.11 tar/gz <http://botan.randombit.net/files/Botan-1.8.11.tgz>`_ -(`1.8.11 tar/gz sig <http://botan.randombit.net/files/Botan-1.8.11.tgz.asc>`_), +`1.10.1 tar/gz <http://botan.randombit.net/files/Botan-1.10.1.tgz>`_ +(`1.10.1 tar/gz sig <http://botan.randombit.net/files/Botan-1.10.1.tgz.asc>`_), -`1.8.11 tar/bzip <http://botan.randombit.net/files/Botan-1.8.11.tbz>`_ -(`1.8.11 tar/bzip sig <http://botan.randombit.net/files/Botan-1.8.11.tbz.asc>`_) +`1.10.1 tar/bzip <http://botan.randombit.net/files/Botan-1.10.1.tbz>`_ +(`1.10.1 tar/bzip sig <http://botan.randombit.net/files/Botan-1.10.1.tbz.asc>`_) -Windows binary installer for use with Visual C++ 2008: +.. + Windows binary installer for use with Visual C++ 2010: -`1.8.11 x86-32 installer -<http://botan.randombit.net/files/win32/botan-1.8.11_win32.exe>`_ + `1.10.1 x86-32 installer + <http://botan.randombit.net/files/win32/botan-1.10.1_win32.exe>`_ -`1.8.11 x86-64 installer -<http://botan.randombit.net/files/win32/botan-1.8.11_win64.exe>`_ + `1.10.1 x86-64 installer + <http://botan.randombit.net/files/win32/botan-1.10.1_win64.exe>`_ -Current Development Release +Previous Stable Release (1.8) ---------------------------------------- -The current development release is `1.9.16 -<http://botan.randombit.net/news/releases/1_9_16.html>`_ which was -released on 2011-04-11. +The previous stable release is `1.8.13 +<http://botan.randombit.net/news/releases/1_8_13.html>`_ which was +released on 2011-07-02. Sources: -`1.9.16 tar/gz <http://botan.randombit.net/files/Botan-1.9.16.tgz>`_ -(`1.9.16 tar/gz sig <http://botan.randombit.net/files/Botan-1.9.16.tgz.asc>`_), +`1.8.13 tar/gz <http://botan.randombit.net/files/Botan-1.8.13.tgz>`_ +(`1.8.13 tar/gz sig <http://botan.randombit.net/files/Botan-1.8.13.tgz.asc>`_), -`1.9.16 tar/bzip <http://botan.randombit.net/files/Botan-1.9.16.tbz>`_ -(`1.9.16 tar/bzip sig <http://botan.randombit.net/files/Botan-1.9.16.tbz.asc>`_) +`1.8.13 tar/bzip <http://botan.randombit.net/files/Botan-1.8.13.tbz>`_ +(`1.8.13 tar/bzip sig <http://botan.randombit.net/files/Botan-1.8.13.tbz.asc>`_) -Windows binary installer for use with Visual C++ 2010: +.. + Windows binary installer for use with Visual C++ 2008: -`1.9.17-pre x86-32 installer -<http://botan.randombit.net/files/win32/botan-1.9.17_win32.exe>`_ + `1.8.13 x86-32 installer + <http://botan.randombit.net/files/win32/botan-1.8.13_win32.exe>`_ -`1.9.17-pre x86-64 installer -<http://botan.randombit.net/files/win32/botan-1.9.17_win64.exe>`_ + `1.8.13 x86-64 installer + <http://botan.randombit.net/files/win32/botan-1.8.13_win64.exe>`_ Accessing Version Control ---------------------------------------- @@ -66,8 +68,9 @@ Botan's development occurs using a distributed version control system called `Monotone <http://www.monotone.ca>`_. The main branch of development occurs on the branch named -``net.randombit.botan``; this is probably the branch you want. To -download that branch and set up a new workspace, run:: +``net.randombit.botan``; this is probably the branch you want (for +1.8, use ``net.randombit.botan.1_8`` instead). To download that branch +and set up a new workspace, run:: $ mtn db init --db=botan.mtn $ mtn pull --db=botan.mtn randombit.net 'net.randombit.botan' diff --git a/doc/examples/GNUmakefile b/doc/examples/GNUmakefile index 44fcfeea5..a5da47a7c 100644 --- a/doc/examples/GNUmakefile +++ b/doc/examples/GNUmakefile @@ -3,7 +3,7 @@ BOTAN_CONFIG = botan-config CXX = g++ CFLAGS = -O2 -ansi -W -Wall -I../../build/include -LIBS = -L../.. -lbotan +LIBS = -L../.. -lbotan-1.10 SRCS=$(wildcard *.cpp) diff --git a/doc/examples/cpuid.cpp b/doc/examples/cpuid.cpp index 6d4cc7593..bd81e417b 100644 --- a/doc/examples/cpuid.cpp +++ b/doc/examples/cpuid.cpp @@ -42,5 +42,6 @@ int main() print_if_feature("RDTSC", CPUID::has_rdtsc()); print_if_feature("PCMUL", CPUID::has_pcmuludq()); print_if_feature("AES-NI", CPUID::has_aes_ni()); + print_if_feature("RDRND", CPUID::has_rdrand()); print_if_feature("MOVBE", CPUID::has_movbe()); } diff --git a/doc/examples/socket.h b/doc/examples/socket.h index c4fa46600..f7ce98fea 100644 --- a/doc/examples/socket.h +++ b/doc/examples/socket.h @@ -10,13 +10,57 @@ #include <stdexcept> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netinet/in.h> -#include <netdb.h> -#include <unistd.h> -#include <errno.h> +#if defined(_MSC_VER) + #define SOCKET_IS_WINSOCK 1 +#endif + +#if !defined(SOCKET_IS_WINSOCK) + #define SOCKET_IS_WINSOCK 0 +#endif + +#if SOCKET_IS_WINSOCK + #include <winsock.h> + + typedef SOCKET socket_t; + const socket_t invalid_socket = INVALID_SOCKET; + #define socket_error_code WSAGetLastError() + typedef int ssize_t; + + class SocketInitializer + { + public: + SocketInitializer() + { + WSADATA wsadata; + WSAStartup(MAKEWORD(2, 2), &wsadata); + } + + ~SocketInitializer() + { + WSACleanup(); + } + }; +#else + #include <sys/types.h> + #include <sys/socket.h> + #include <sys/time.h> + #include <netinet/in.h> + #include <netdb.h> + #include <unistd.h> + #include <errno.h> + + typedef int socket_t; + const socket_t invalid_socket = -1; + #define socket_error_code errno + #define closesocket close + + class SocketInitializer {}; +#endif + +#if !defined(MSG_NOSIGNAL) + #define MSG_NOSIGNAL 0 +#endif + #include <string.h> class Socket @@ -29,15 +73,15 @@ class Socket void close() { - if(sockfd != -1) + if(sockfd != invalid_socket) { - if(::close(sockfd) != 0) + if(::closesocket(sockfd) != 0) throw std::runtime_error("Socket::close failed"); - sockfd = -1; + sockfd = invalid_socket; } } - Socket(int fd, const std::string& peer_id = "") : + Socket(socket_t fd, const std::string& peer_id = "") : peer(peer_id), sockfd(fd) { } @@ -46,7 +90,7 @@ class Socket ~Socket() { close(); } private: std::string peer; - int sockfd; + socket_t sockfd; }; class Server_Socket @@ -57,26 +101,26 @@ class Server_Socket */ Socket* accept() { - int retval = ::accept(sockfd, 0, 0); - if(retval == -1) + socket_t retval = ::accept(sockfd, 0, 0); + if(retval == invalid_socket) throw std::runtime_error("Server_Socket: accept failed"); return new Socket(retval); } void close() { - if(sockfd != -1) + if(sockfd != invalid_socket) { - if(::close(sockfd) != 0) + if(::closesocket(sockfd) != 0) throw std::runtime_error("Server_Socket::close failed"); - sockfd = -1; + sockfd = invalid_socket; } } Server_Socket(unsigned short); ~Server_Socket() { close(); } private: - int sockfd; + socket_t sockfd; }; /** @@ -84,7 +128,7 @@ class Server_Socket */ Socket::Socket(const std::string& host, unsigned short port) : peer(host) { - sockfd = -1; + sockfd = invalid_socket; hostent* host_addr = ::gethostbyname(host.c_str()); @@ -93,8 +137,8 @@ Socket::Socket(const std::string& host, unsigned short port) : peer(host) if(host_addr->h_addrtype != AF_INET) // FIXME throw std::runtime_error("Socket: " + host + " has IPv6 address"); - int fd = ::socket(PF_INET, SOCK_STREAM, 0); - if(fd == -1) + socket_t fd = ::socket(PF_INET, SOCK_STREAM, 0); + if(fd == invalid_socket) throw std::runtime_error("Socket: Unable to acquire socket"); sockaddr_in socket_info; @@ -110,7 +154,7 @@ Socket::Socket(const std::string& host, unsigned short port) : peer(host) if(::connect(fd, (sockaddr*)&socket_info, sizeof(struct sockaddr)) != 0) { - ::close(fd); + ::closesocket(fd); throw std::runtime_error("Socket: connect failed"); } @@ -122,21 +166,22 @@ Socket::Socket(const std::string& host, unsigned short port) : peer(host) */ size_t Socket::read(unsigned char buf[], size_t length) { - if(sockfd == -1) + if(sockfd == invalid_socket) throw std::runtime_error("Socket::read: Socket not connected"); size_t got = 0; while(length) { - ssize_t this_time = ::recv(sockfd, buf + got, length, MSG_NOSIGNAL); + ssize_t this_time = ::recv(sockfd, (char*)buf + got, + length, MSG_NOSIGNAL); if(this_time == 0) break; if(this_time == -1) { - if(errno == EINTR) + if(socket_error_code == EINTR) this_time = 0; else throw std::runtime_error("Socket::read: Socket read failed"); @@ -153,17 +198,18 @@ size_t Socket::read(unsigned char buf[], size_t length) */ void Socket::write(const unsigned char buf[], size_t length) { - if(sockfd == -1) + if(sockfd == invalid_socket) throw std::runtime_error("Socket::write: Socket not connected"); size_t offset = 0; while(length) { - ssize_t sent = ::send(sockfd, buf + offset, length, MSG_NOSIGNAL); + ssize_t sent = ::send(sockfd, (const char*)buf + offset, + length, MSG_NOSIGNAL); if(sent == -1) { - if(errno == EINTR) + if(socket_error_code == EINTR) sent = 0; else throw std::runtime_error("Socket::write: Socket write failed"); @@ -179,10 +225,10 @@ void Socket::write(const unsigned char buf[], size_t length) */ Server_Socket::Server_Socket(unsigned short port) { - sockfd = -1; + sockfd = invalid_socket; - int fd = ::socket(PF_INET, SOCK_STREAM, 0); - if(fd == -1) + socket_t fd = ::socket(PF_INET, SOCK_STREAM, 0); + if(fd == invalid_socket) throw std::runtime_error("Server_Socket: Unable to acquire socket"); sockaddr_in socket_info; @@ -195,13 +241,13 @@ Server_Socket::Server_Socket(unsigned short port) if(::bind(fd, (sockaddr*)&socket_info, sizeof(struct sockaddr)) != 0) { - ::close(fd); + ::closesocket(fd); throw std::runtime_error("Server_Socket: bind failed"); } - if(listen(fd, 100) != 0) // FIXME: totally arbitrary + if(::listen(fd, 100) != 0) // FIXME: totally arbitrary { - ::close(fd); + ::closesocket(fd); throw std::runtime_error("Server_Socket: listen failed"); } diff --git a/doc/examples/tls_client.cpp b/doc/examples/tls_client.cpp index eb4a98817..cedfe1ca8 100644 --- a/doc/examples/tls_client.cpp +++ b/doc/examples/tls_client.cpp @@ -35,13 +35,15 @@ int main(int argc, char* argv[]) try { - LibraryInitializer init; + LibraryInitializer botan_init; std::string host = argv[1]; u32bit port = argc == 3 ? Botan::to_u32bit(argv[2]) : 443; printf("Connecting to %s:%d...\n", host.c_str(), port); + SocketInitializer socket_init; + Socket sock(argv[1], port); AutoSeeded_RNG rng; @@ -54,10 +56,15 @@ int main(int argc, char* argv[]) printf("Handshake extablished...\n"); +#if 0 std::string http_command = "GET / HTTP/1.1\r\n" "Server: " + host + ':' + to_string(port) + "\r\n\r\n"; +#else + std::string http_command = "GET / HTTP/1.0\r\n\r\n"; +#endif - tls.write((const byte*)http_command.c_str(), http_command.length()); + tls.write((const Botan::byte*)http_command.c_str(), + http_command.length()); size_t total_got = 0; @@ -66,7 +73,7 @@ int main(int argc, char* argv[]) if(tls.is_closed()) break; - byte buf[128+1] = { 0 }; + Botan::byte buf[128+1] = { 0 }; size_t got = tls.read(buf, sizeof(buf)-1); printf("%s", buf); fflush(0); diff --git a/doc/examples/tls_server.cpp b/doc/examples/tls_server.cpp index be5677c12..153b26d04 100644 --- a/doc/examples/tls_server.cpp +++ b/doc/examples/tls_server.cpp @@ -39,7 +39,8 @@ int main(int argc, char* argv[]) try { - LibraryInitializer init; + LibraryInitializer botan_init; + SocketInitializer socket_init; AutoSeeded_RNG rng; @@ -81,12 +82,12 @@ int main(int argc, char* argv[]) printf("Writing some text\n"); char msg[] = "Foo\nBar\nBaz\nQuux\n"; - tls.write((const byte*)msg, strlen(msg)); + tls.write((const Botan::byte*)msg, strlen(msg)); printf("Now trying a read...\n"); char buf[1024] = { 0 }; - u32bit got = tls.read((byte*)buf, sizeof(buf)-1); + u32bit got = tls.read((Botan::byte*)buf, sizeof(buf)-1); printf("%d: '%s'\n", got, buf); tls.close(); diff --git a/doc/faq.txt b/doc/faq.txt index 38be253a7..9658621fe 100644 --- a/doc/faq.txt +++ b/doc/faq.txt @@ -28,16 +28,20 @@ stability between releases on the development branch, and API changes may be made without notice. Feel free to send comments on API changes, or API problems, to the list. -If you want to ship a binary that is usable out of the box on a Linux -distro that ships botan (most do), or you want to ensure you're not -having to track a moving target, you'll probably prefer using the +If you don't want to have to worry about tracking a moving target, and +just want something that works, you'll probably prefer using the stable releases. If you want to get the latest features, the -development releases are the obvious choice. If you're building an -application that will embed botan into it (without relying on a shared -library), you want to use an amalgamation build, which basically turns -botan into a single header and a single source file which you can -easily include in your existing application build; this feature is -currently only available in the development trees. +development releases are the obvious choice. + +If you want to ship a binary that is usable out of the box on a Linux +distro that ships botan, you'll probably want to match versions with +that distro; as of this writing most ship with 1.8. + +If you're building an application that will embed botan into it +(without relying on a shared library), you want to use an amalgamation +build, which basically turns botan into a single header and a single +source file which you can easily include in your existing application +build. In this case you can pick which ever tree you prefer. The self-test program can't locate the library ----------------------------------------------- @@ -88,7 +92,7 @@ to use. For unencrypted keys, you can also manually decode the parameters using the existing PEM and BER support; see `this post -<http://lists.randombit.net/pipermail/botan-devel/2010-June/001157.html>`_ +<http://lists.randombit.net/pipermail/botan-devel/2010-June/001156.html>`_ to the dev list for an example. Is botan FIPS 140 certified? @@ -155,7 +159,7 @@ You can do any combination of: * Contact the current lead maintainer personally; currently `Jack Lloyd <http://www.randombit.net>`_ - (`personal PGP key` <http://www.randombit.net/pgpgkey.html`_) + (`personal PGP key <http://www.randombit.net/pgpgkey.html>`_) * Email the `development list <http://lists.randombit.net/mailman/listinfo/botan-devel>`_ @@ -165,8 +169,8 @@ You can do any combination of: Does botan support SSL/TLS, SSH, S/MIME, OpenPGP... ------------------------------------------------------------ -Support for SSL/TLS is included in the most recent development -releases (1.9.x). Currently SSLv3 and TLS 1.0 and 1.1 are supported. +Support for SSL/TLS is included in version 1.9.4 and later. Currently +SSLv3 and TLS 1.0 and 1.1 are supported. `NetSieben SSH <http://netsieben.com/products/ssh/>`_ is an open source SSHv2 implementation that uses botan. @@ -181,9 +185,8 @@ Will it work on my platform XYZ?? ---------------------------------------- The most common stumbling block is a compiler that is buggy or can't -handle modern C++ (specifically, C++98). Check out the `build list -<http://botan.randombit.net/builds.html>`_ for a sense of which -platforms are actively being tested. +handle modern C++ (specifically, C++98). Check out the :doc:`build log +<build_log>` for a sense of which platforms are actively being tested. I'm not feeling this, what can I use instead? ------------------------------------------------------------ diff --git a/doc/fpe.txt b/doc/fpe.txt index 243be87d9..5c035f0b7 100644 --- a/doc/fpe.txt +++ b/doc/fpe.txt @@ -2,6 +2,8 @@ Format Preserving Encryption ======================================== +.. versionadded:: 1.9.17 + Format preserving encryption (FPE) refers to a set of techniques for encrypting data such that the ciphertext has the same format as the plaintext. For instance, you can use FPE to encrypt credit card diff --git a/doc/welcome.txt b/doc/index.txt index 430a71f20..75e2ca434 100644 --- a/doc/welcome.txt +++ b/doc/index.txt @@ -9,8 +9,9 @@ provides applications with most any :doc:`cryptographic algorithm message processing system <filters>`, and a wide variety of other features. A third party open source implementation of `SSHv2 <http://www.netsieben.com/products/ssh/>`_ that uses botan is also -available. In addition to C++ you can use botan from Python or Perl, -though the current bindings only wrap portions of the library. +available. In addition to C++ you can use botan from :doc:`Python +<python>` or Perl, though the current bindings only wrap portions of +the library. See the :doc:`faq` for a list of common questions and answers. @@ -47,7 +48,7 @@ already included in most major package distributions, including more than a few :doc:`known users <users>`. It was started as a personal project by `Jack Lloyd -<http:://www.randombit.net>`_,who continues to be the maintainer and +<http://www.randombit.net>`_,who continues to be the maintainer and release manager. Since the first release in 2001, a number of :doc:`individuals and organizations <credits>` have contributed bug fixes and new features. Check out the :doc:`release notes <log>` and @@ -66,25 +67,3 @@ be a bug, please file a ticket in `Bugzilla A useful reference while reading this manual is the `Doxygen documentation <http://botan.randombit.net/doxygen>`_. -Recommended Reading -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -It's a very good idea if you have some knowledge of cryptography -*before* trying to use the library. This is an area where it is very -easy to make mistakes, and where things are often subtle and/or -counterintuitive. Obviously the library tries to provide things at a -high level precisely to minimize the number of ways things can go -wrong, but naive use will almost certainly not result in a secure -system. - -Especially recommended are: - -- *Cryptography Engineering* - Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno - -- *Security Engineering -- A Guide to Building Dependable Distributed Systems* - Ross Anderson - -- *Handbook of Applied Cryptography* - Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone - (`available online <http://www.cacr.math.uwaterloo.ca/hac/>`_) diff --git a/doc/log.txt b/doc/log.txt index 7e00e87c2..478b27a94 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -4,12 +4,172 @@ Release Notes ======================================== +Series 1.10 +---------------------------------------- + +Version 1.10.2, Not Yet Released +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* The SSL/TLS code is disabled by default in this release. A new + version is being developed and the current iteration should not be + used unless needed for existing code. + +* Add the Camellia block cipher + +* An implementation of SRP-6a compatible with the specification in + RFC 5054 is now available in srp6.h + +* The exception catching syntax of configure.py has been changed to + the Python 3.x syntax. This syntax also works with Python 2.6 and + 2.7, but not with any earlier Python 2 release. A simple search and + replace will allow running it under Python 2.5:: + perl -pi -e 's/except (.*) as (.*):/except $1, $2:/g' configure.py + +* If clock_gettime is available on the system, poll all available + clock types in the hres_timer poll. + +* Add AltiVec detection for IBM POWER7 processors. + +* Add AltiVec detection for OpenBSD, contributed by Brad Smith (PR 162) + +* Add Google's Native Client as an compile target + +* If targetting GCC on a Windows system, configure.py will warn that + likely you wanted to configure for either MinGW or Cygwin, not the + generic Windows target which is oriented to Win32 plus the Visual + C++ runtime. + +* Fixed a compilation problem of the dynamic loader hooks under MinGW GCC + +* Don't set a soname on OpenBSD, as it doesn't support it (PR 158) + +* Fix a configure.py incompatability with the subprocess module + included in Python 3.1 (PR 157) + +* A bug in configure.py would cause it to interpret `--cpu=s390x` as + `s390`. This may have affected other CPUs as well. Now configure.py + searches for an exact match, and only if no exact match is found + will it search for substring matches. + +Version 1.10.1, 2011-07-11 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* A race condition in `Algorithm_Factory` could cause crashes in + multithreaded code. See `this thread on botan-devel + <http://lists.randombit.net/pipermail/botan-devel/2011-July/001455.html>`_ + for details and workarounds. + +* The return value of ``name`` has changed for GOST 28147-89 and + Skein-512. GOST's ``name`` now includes the name of the sbox, and + Skein's includes the personalization string (if nonempty). This + allows an object to be properly roundtripped, which is necessary to + fix the race condition described above. + +* A new distribution script is now included, as + ``src/build-data/scripts/dist.py`` + +* The ``build.h`` header now includes, if available, an identifier of + the source revision that was used. This identifier is also included + in the result of ``version_string``. + +Version 1.10.0, 2011-06-20 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Detection for the rdrand instruction being added to upcoming Intel + Ivy Bridge processors has been added. + +* A template specialization of std::swap was added for the memory + container types. + Series 1.9 ---------------------------------------- -Version 1.9.17, Not Yet Released +Version 1.9.18, 2011-06-03 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* Fourth release candidate for 1.10.0 + +* The GOST 34.10 verification operation was not ensuring that s and r + were both greater than zero. This could potentially have meant it + would have accepted an invalid all-zero signature as valid for any + message. Due to how ECC points are internally represented it instead + resulted in an exception being thrown. + +* A simple multiexponentation algorithm is now used in ECDSA and + GOST-34.10 signature verification, leading to 20 to 25% improvements + in ECDSA and 25% to 40% improvements in GOST-34.10 verification + performance. + +* The internal representation of elliptic curve points has been + modified to use Montgomery representation exclusively, resulting in + reduced memory usage and a 10 to 20% performance improvement for + ECDSA and ECDH. + +* In OAEP decoding, scan for the delimiter bytes using a loop that is + written without conditionals so as to help avoid timing analysis. + Unfortunately GCC at least is 'smart' enough to compile it to + jumps anyway. + +* The SSE2 implementation of IDEA did not work correctly when compiled + by Clang, because the trick it used to emulate a 16 bit unsigned + compare in SSE (which doesn't contain one natively) relied on signed + overflow working in the 'usual' way. A different method that doesn't + rely on signed overflow is now used. + +* Add support for compiling SSL using Visual C++ 2010's TR1 + implementation. + +* Fix a bug under Visual C++ 2010 which would cause ``hex_encode`` to + crash if given a zero-sized input to encode. + +* A new build option ``--via-amalgamation`` will first generate the + single-file amalgamation, then build the library from that single + file. This option requires a lot of memory and does not parallelize, + but the resulting library is smaller and may be faster. + +* On Unix, the library and header paths have been changed to allow + parallel installation of different versions of the library. Headers + are installed into ``<prefix>/include/botan-1.9/botan``, libraries + are named ``libbotan-1.9``, and ``botan-config`` is now namespaced + (so in this release ``botan-config-1.9``). All of these embedded + versions will be 1.10 in the upcoming stable release. + +* The soname system has been modified. In this release the library + soname is ``libbotan-1.9.so.0``, with the full library being named + ``libbotan-1.9.so.0.18``. The ``0`` is the ABI version, and will be + incremented whenever a breaking ABI change is made. + +* TR1 support is not longer automatically assumed under older versions + of GCC + +* Functions for base64 decoding that work standalone (without needing + to use a pipe) have been added to ``base64.h`` + +* The function ``BigInt::to_u32bit`` was inadvertently removed in 1.9.11 + and has been added back. + +* The function ``BigInt::get_substring`` did not work correctly with a + *length* argument of 32. + +* The implementation of ``FD_ZERO`` on Solaris uses ``memset`` and + assumes the caller included ``string.h`` on its behalf. Do so to + fix compilation in the ``dev_random`` and ``unix_procs`` entropy + sources. Patch from Jeremy C. Reed. + +* Add two different configuration targets for Atom, since some are + 32-bit and some are 64-bit. The 'atom' target now refers to the + 64-bit implementations, use 'atom32' to target the 32-bit + processors. + +* The (incomplete) support for CMS and card verifiable certificates + are disabled by default; add ``--enable-modules=cms`` or + ``--enable-modules=cvc`` during configuration to turn them back on. + +Version 1.9.17, 2011-04-29 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Third release candidate for 1.10.0 + * The format preserving encryption method currently available was presented in the header ``fpe.h`` and the functions ``fpe_encrypt`` and ``fpe_decrypt``. These were renamed as it is likely that other @@ -36,6 +196,15 @@ Version 1.9.17, Not Yet Released ``BOTAN_TARGET_ARCH_IS_X86_32``. The classes calling assembly have also been renamed. +* Similiarly to the above change, the AES implemenations using the + AES-NI instruction set have been renamed from AES_XXX_Intel to + AES_XXX_NI. + +* Systems that are identified as `sun4u` will default to compiling for + 32-bit SPARCv9 code rather than 64-bit. This matches the still + common convention for 32-bit SPARC userspaces. If you want 64-bit + code on such as system, use ``--cpu=sparc64``. + * Some minor fixes for compiling botan under the BeOS clone/continuation `Haiku <http://haiku-os.org>`_. @@ -320,6 +489,28 @@ Version 1.9.0, 2009-09-09 Series 1.8 ---------------------------------------- +Version 1.8.13, 2011-07-02 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* A race condition in `Algorithm_Factory` could cause crashes in + multithreaded code. See `this thread on botan-devel + <http://lists.randombit.net/pipermail/botan-devel/2011-July/001455.html>`_ + for details and workarounds. + +Version 1.8.12, 2011-06-20 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* If EMSA3(Raw) was used for more than one signature, it would produce + incorrect output. + +* Fix the --enable-debug option to configure.py + +* Improve OS detection on Cygwin + +* Fix compilation under Sun Studio 12 on Solaris + +* Fix a memory leak in the constructors of DataSource_Stream and + DataSink_Stream which would occur if opening the file failed. PR 144 + Version 1.8.11, 2010-11-02 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/old/insito_manual.pdf b/doc/old/insito_manual.pdf Binary files differdeleted file mode 100644 index b07146992..000000000 --- a/doc/old/insito_manual.pdf +++ /dev/null diff --git a/doc/pgpkey.txt b/doc/pgpkey.txt index 1d2f3debc..ef8827835 100644 --- a/doc/pgpkey.txt +++ b/doc/pgpkey.txt @@ -2,6 +2,8 @@ PGP Code Signing Key ======================================== +.. highlight:: none + The following PGP key is used to sign all releases:: pub 2048R/EFBADFBC 2004-10-30 diff --git a/doc/python.txt b/doc/python.txt new file mode 100644 index 000000000..dcd274eed --- /dev/null +++ b/doc/python.txt @@ -0,0 +1,14 @@ + +Python Binding +======================================== + +.. highlight:: python + +.. note:: + + The Python binding should be considered alpha software, and the + interfaces may change in the future. + +Botan includes a binding for Python, implemented using Boost.Python. + +.. literalinclude:: examples/python/rsa.py diff --git a/doc/reading.txt b/doc/reading.txt new file mode 100644 index 000000000..a0e547296 --- /dev/null +++ b/doc/reading.txt @@ -0,0 +1,23 @@ + +Recommended Reading +======================================== + +It's a very good idea if you have some knowledge of cryptography +*before* trying to use the library. This is an area where it is very +easy to make mistakes, and where things are often subtle and/or +counterintuitive. Obviously the library tries to provide things at a +high level precisely to minimize the number of ways things can go +wrong, but naive use will almost certainly not result in a secure +system. + +Especially recommended are: + +- *Cryptography Engineering* + Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno + +- *Security Engineering -- A Guide to Building Dependable Distributed Systems* + Ross Anderson + +- *Handbook of Applied Cryptography* + Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone + (`available online <http://www.cacr.math.uwaterloo.ca/hac/>`_) diff --git a/doc/ssl.txt b/doc/ssl.txt index 7b61fa88c..f536b7198 100644 --- a/doc/ssl.txt +++ b/doc/ssl.txt @@ -4,6 +4,8 @@ SSL and TLS ======================================== +.. versionadded:: 1.9.4 + Botan supports both client and server implementations of the SSL/TLS protocols, including SSL v3, TLS v1.0, and TLS v1.1. The insecure and obsolete SSL v2 is not supported. @@ -15,7 +17,35 @@ feature macro ``BOTAN_HAS_SSL_TLS`` to check. TLS Clients ---------------------------------------- -A simple TLS client: +.. cpp:class:: TLS_Client + + .. cpp:function:: TLS_Client( \ + std::tr1::function<size_t, byte*, size_t> input_fn, \ + std::tr1::function<void, const byte*, size_t> output_fn, \ + const TLS_Policy& policy, RandomNumberGenerator& rng) + + Creates a TLS client. It will call *input_fn* to read bytes from + the network and call *output_fn* when bytes need to be written to + the network. + + .. cpp:function:: size_t read(byte* buf, size_t buf_len) + + Reads up to *buf_len* bytes from the open connection into *buf*, + returning the number of bytes actually written. + + .. cpp:function:: void write(const byte* buf, size_t buf_len) + + Writes *buf_len* bytes in *buf* to the remote side + + .. cpp:function:: void close() + + Closes the connection + + .. cpp:function:: std::vector<X509_Certificate> peer_cert_chain() + + Returns the certificate chain of the server + +A simple TLS client example: .. literalinclude:: examples/tls_client.cpp diff --git a/doc/users.txt b/doc/users.txt index 9c7d274d3..a48d9e60b 100644 --- a/doc/users.txt +++ b/doc/users.txt @@ -28,25 +28,25 @@ Open Source Software crypto provider <http://websvn.kde.org/trunk/kdesupport/qca/src/botantools/botan/>`_. +* `TCHead <http://16s.us/TCHead/>`_ is a utility for analyzing + TrueCrypt volume headers. + +* `Octopod <http://code.google.com/p/octopod/>`_ is a + file sharing system. + * `Silverlock <http://www.petroules.com/products/silverlock/>`_ is a GPL password management tool for Windows, OS X, and Linux.</p> -* `eVersys <http://code.google.com/p/eversys/>`_ is a GPL - alternative to Rational ClearCase. - * `Monotone <http://monotone.ca/>`_, a free distributed version control system, uses botan for RSA authentication, content hashing, and message authentication. -* `Publimark <http://perso.wanadoo.fr/gleguelv/soft/>`_, a - tool for hiding messages in an audio file. +* `Publimark <http://www.gleguelv.org/soft/publimark/index.html>`_ + is a tool for hiding messages in an audio file. -* `KeySafe <http://www.gnomefiles.org/app.php/KeySafe>`_, +* `KeySafe <http://therning.org/magnus/computer/keysafe>`_, a password application for GNOME -* `Octopod <http://code.google.com/p/octopod/>`_ is a - file sharing system. - * `SuSE <http://gcc.opensuse.org>`_ uses botan as part of a test suite for the GCC optimizer. @@ -56,10 +56,6 @@ Open Source Software * `VNCcrack <http://www.randombit.net/code/vnccrack/>`_ is a password cracker for the VNC authentication/response protocol. -* `Cutlass <http://www.synacklabs.net/projects/cutlass/>`_, an - encrypted P2P system providing IM, file transfer, and VoIP, used - botan. - Commercial Software ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -79,9 +75,6 @@ Commercial Software * `TextEgg <http://www.textegg.com/>`_ is an encrypted document editor. -* `Trillian Astra <http://www.trillianastra.com>`_, Cerulean Studios - IM client, uses botan - * `Seagate <http://www.seagate.com/www/en-us/support/downloads/>`_ uses botan for the drive encryption in the Maxtor OneTouch III Mini Edition hard drive. @@ -89,12 +82,8 @@ Commercial Software * `Aegeus Technology Ltd <http://www.aegeus-technology.com>`_ used botan in a research implementation of SPKI. -* `Portalsphere <http://www.portalsphere.com>`_, a CORBA based - application server, provides access to botan (though a Tcl wrapper) - to application developers. - -* `E.V.E. Paradox <http://www.eveparadox.com>`_, a suite of games for - Windows, uses botan. +* `E.V.E. Paradox <http://www.entropicsoftware.com/eve/eve.html>`_, a + suite of games for Windows. Research Projects ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/readme.txt b/readme.txt index 35eedfc17..f7bc55f61 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ -Botan 1.9.17, Not Yet Released +Botan 1.10.2, ????-??-?? http://botan.randombit.net/ Botan is a C++ class library for performing a wide variety of @@ -8,8 +8,8 @@ Bugzilla (http://bugs.randombit.net/) or by sending a report to the botan-devel mailing list. More information about the mailing list is at http://lists.randombit.net/mailman/listinfo/botan-devel/ -You can find documentation online at http://botan.randombit.net/docs -and http://botan.randombit.net/doxygen. A set of example programs can -be found in the examples directory. +You can find documentation online at http://botan.randombit.net/ as +well as in the doc directory in the distribution. Several examples can +be found in doc/examples as well. Jack Lloyd ([email protected]) diff --git a/src/algo_factory/algo_cache.h b/src/algo_factory/algo_cache.h index 0d891ad3f..25f2db023 100644 --- a/src/algo_factory/algo_cache.h +++ b/src/algo_factory/algo_cache.h @@ -1,6 +1,6 @@ /* * An algorithm cache (used by Algorithm_Factory) -* (C) 2008-2009 Jack Lloyd +* (C) 2008-2009,2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -171,14 +171,16 @@ void Algorithm_Cache<T>::add(T* algo, Mutex_Holder lock(mutex); - delete algorithms[algo->name()][provider]; - algorithms[algo->name()][provider] = algo; - if(algo->name() != requested_name && aliases.find(requested_name) == aliases.end()) { aliases[requested_name] = algo->name(); } + + if(!algorithms[algo->name()][provider]) + algorithms[algo->name()][provider] = algo; + else + delete algo; } /* diff --git a/src/alloc/alloc_mmap/mmap_mem.cpp b/src/alloc/alloc_mmap/mmap_mem.cpp index 78177bcdd..e4b602764 100644 --- a/src/alloc/alloc_mmap/mmap_mem.cpp +++ b/src/alloc/alloc_mmap/mmap_mem.cpp @@ -85,20 +85,22 @@ void* MemoryMapping_Allocator::alloc_block(size_t n) if(file.get_fd() == -1) throw MemoryMapping_Failed("Could not create file"); - std::vector<byte> zeros(n); + std::vector<byte> zeros(4096); - ssize_t remaining = n; + size_t remaining = n; while(remaining) { - ssize_t wrote_here = ::write(file.get_fd(), - &zeros[0], - remaining); + const size_t write_try = std::min(zeros.size(), remaining); - if(wrote_here == -1 && errno != EINTR) + ssize_t wrote_got = ::write(file.get_fd(), + &zeros[0], + write_try); + + if(wrote_got == -1 && errno != EINTR) throw MemoryMapping_Failed("Could not write to file"); - remaining -= wrote_here; + remaining -= wrote_got; } #ifndef MAP_NOSYNC diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h index b06be0d55..6c8a75c44 100644 --- a/src/alloc/secmem.h +++ b/src/alloc/secmem.h @@ -34,7 +34,6 @@ class MemoryRegion */ bool empty() const { return (used == 0); } -#if 1 /** * Get a pointer to the first element in the buffer. * @return pointer to the first element in the buffer @@ -46,12 +45,6 @@ class MemoryRegion * @return constant pointer to the first element in the buffer */ operator const T* () const { return buf; } -#else - - T& operator[](size_t n) { return buf[n]; } - const T& operator[](size_t n) const { return buf[n]; } - -#endif /** * Get a pointer to the first element in the buffer. @@ -171,9 +164,9 @@ class MemoryRegion */ void swap(MemoryRegion<T>& other); - ~MemoryRegion() { deallocate(buf, allocated); } + virtual ~MemoryRegion() { deallocate(buf, allocated); } protected: - MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; } + MemoryRegion() : buf(0), used(0), allocated(0), alloc(0) {} /** * Copy constructor @@ -425,4 +418,14 @@ void zeroise(MemoryRegion<T>& vec) } +namespace std { + +template<typename T> +inline void swap(Botan::MemoryRegion<T>& x, Botan::MemoryRegion<T>& y) + { + x.swap(y); + } + +} + #endif diff --git a/src/asn1/alg_id.cpp b/src/asn1/alg_id.cpp index b48db3e50..665e42fb3 100644 --- a/src/asn1/alg_id.cpp +++ b/src/asn1/alg_id.cpp @@ -41,8 +41,12 @@ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, const byte DER_NULL[] = { 0x05, 0x00 }; oid = alg_id; + if(option == USE_NULL_PARAM) - parameters += std::make_pair(DER_NULL, sizeof(DER_NULL)); + { + parameters += std::make_pair<const byte*, size_t>( + DER_NULL, sizeof(DER_NULL)); + } } /* @@ -54,8 +58,12 @@ AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, const byte DER_NULL[] = { 0x05, 0x00 }; oid = OIDS::lookup(alg_id); + if(option == USE_NULL_PARAM) - parameters += std::make_pair(DER_NULL, sizeof(DER_NULL)); + { + parameters += std::make_pair<const byte*, size_t>( + DER_NULL, sizeof(DER_NULL)); + } } /* diff --git a/src/asn1/der_enc.h b/src/asn1/der_enc.h index f80c518b3..183e43b80 100644 --- a/src/asn1/der_enc.h +++ b/src/asn1/der_enc.h @@ -24,30 +24,44 @@ class BOTAN_DLL DER_Encoder public: SecureVector<byte> get_contents(); - DER_Encoder& start_cons(ASN1_Tag, ASN1_Tag = UNIVERSAL); + DER_Encoder& start_cons(ASN1_Tag type_tag, + ASN1_Tag class_tag = UNIVERSAL); DER_Encoder& end_cons(); - DER_Encoder& start_explicit(u16bit); + DER_Encoder& start_explicit(u16bit type_tag); DER_Encoder& end_explicit(); - DER_Encoder& raw_bytes(const byte[], size_t); - DER_Encoder& raw_bytes(const MemoryRegion<byte>&); + DER_Encoder& raw_bytes(const byte val[], size_t len); + DER_Encoder& raw_bytes(const MemoryRegion<byte>& val); DER_Encoder& encode_null(); - DER_Encoder& encode(bool); - DER_Encoder& encode(size_t); - DER_Encoder& encode(const BigInt&); - DER_Encoder& encode(const MemoryRegion<byte>&, ASN1_Tag); - DER_Encoder& encode(const byte[], size_t, ASN1_Tag); - - DER_Encoder& encode(bool, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(size_t, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(const BigInt&, ASN1_Tag, - ASN1_Tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(const MemoryRegion<byte>&, ASN1_Tag, - ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(const byte[], size_t, ASN1_Tag, - ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); + DER_Encoder& encode(bool b); + DER_Encoder& encode(size_t s); + DER_Encoder& encode(const BigInt& n); + DER_Encoder& encode(const MemoryRegion<byte>& v, ASN1_Tag real_type); + DER_Encoder& encode(const byte val[], size_t len, ASN1_Tag real_type); + + DER_Encoder& encode(bool b, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + DER_Encoder& encode(size_t s, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + DER_Encoder& encode(const BigInt& n, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + DER_Encoder& encode(const MemoryRegion<byte>& v, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); + + DER_Encoder& encode(const byte v[], size_t len, + ASN1_Tag real_type, + ASN1_Tag type_tag, + ASN1_Tag class_tag = CONTEXT_SPECIFIC); template<typename T> DER_Encoder& encode_optional(const T& value, const T& default_value) @@ -65,13 +79,21 @@ class BOTAN_DLL DER_Encoder return (*this); } - DER_Encoder& encode(const ASN1_Object&); - DER_Encoder& encode_if(bool, DER_Encoder&); + DER_Encoder& encode(const ASN1_Object& obj); + DER_Encoder& encode_if(bool pred, DER_Encoder& enc); + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const byte rep[], size_t length); + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const MemoryRegion<byte>& rep); + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + const std::string& str); + + DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, + byte val); - DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, const byte[], size_t); - DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, const MemoryRegion<byte>&); - DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, const std::string&); - DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, byte); private: class DER_Sequence { @@ -85,6 +107,7 @@ class BOTAN_DLL DER_Encoder SecureVector<byte> contents; std::vector< SecureVector<byte> > set_contents; }; + SecureVector<byte> contents; std::vector<DER_Sequence> subsequences; }; diff --git a/src/block/aes_intel/aes_intel.cpp b/src/block/aes_ni/aes_ni.cpp index a2e660f2c..3ee0e608c 100644 --- a/src/block/aes_intel/aes_intel.cpp +++ b/src/block/aes_ni/aes_ni.cpp @@ -1,11 +1,11 @@ /* -* AES using Intel's AES-NI instructions +* AES using AES-NI instructions * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/aes_intel.h> +#include <botan/aes_ni.h> #include <botan/loadstor.h> #include <wmmintrin.h> @@ -103,7 +103,7 @@ __m128i aes_256_key_expansion(__m128i key, __m128i key2) /* * AES-128 Encryption */ -void AES_128_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_128_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -179,7 +179,7 @@ void AES_128_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-128 Decryption */ -void AES_128_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_128_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -255,7 +255,7 @@ void AES_128_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-128 Key Schedule */ -void AES_128_Intel::key_schedule(const byte key[], size_t) +void AES_128_NI::key_schedule(const byte key[], size_t) { #define AES_128_key_exp(K, RCON) \ aes_128_key_expansion(K, _mm_aeskeygenassist_si128(K, RCON)) @@ -304,7 +304,7 @@ void AES_128_Intel::key_schedule(const byte key[], size_t) /* * Clear memory of sensitive data */ -void AES_128_Intel::clear() +void AES_128_NI::clear() { zeroise(EK); zeroise(DK); @@ -313,7 +313,7 @@ void AES_128_Intel::clear() /* * AES-192 Encryption */ -void AES_192_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_192_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -395,7 +395,7 @@ void AES_192_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-192 Decryption */ -void AES_192_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_192_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -477,7 +477,7 @@ void AES_192_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-192 Key Schedule */ -void AES_192_Intel::key_schedule(const byte key[], size_t) +void AES_192_NI::key_schedule(const byte key[], size_t) { __m128i K0 = _mm_loadu_si128((const __m128i*)(key)); __m128i K1 = _mm_loadu_si128((const __m128i*)(key + 8)); @@ -520,7 +520,7 @@ void AES_192_Intel::key_schedule(const byte key[], size_t) /* * Clear memory of sensitive data */ -void AES_192_Intel::clear() +void AES_192_NI::clear() { zeroise(EK); zeroise(DK); @@ -529,7 +529,7 @@ void AES_192_Intel::clear() /* * AES-256 Encryption */ -void AES_256_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_256_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -617,7 +617,7 @@ void AES_256_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-256 Decryption */ -void AES_256_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_256_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -705,7 +705,7 @@ void AES_256_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-256 Key Schedule */ -void AES_256_Intel::key_schedule(const byte key[], size_t) +void AES_256_NI::key_schedule(const byte key[], size_t) { __m128i K0 = _mm_loadu_si128((const __m128i*)(key)); __m128i K1 = _mm_loadu_si128((const __m128i*)(key + 16)); @@ -770,7 +770,7 @@ void AES_256_Intel::key_schedule(const byte key[], size_t) /* * Clear memory of sensitive data */ -void AES_256_Intel::clear() +void AES_256_NI::clear() { zeroise(EK); zeroise(DK); diff --git a/src/block/aes_intel/aes_intel.h b/src/block/aes_ni/aes_ni.h index a8e6b53e8..ae9e5b3f4 100644 --- a/src/block/aes_intel/aes_intel.h +++ b/src/block/aes_ni/aes_ni.h @@ -1,12 +1,12 @@ /* -* AES using Intel's AES-NI instructions +* AES using AES-NI instructions * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_AES_INTEL_H__ -#define BOTAN_AES_INTEL_H__ +#ifndef BOTAN_AES_NI_H__ +#define BOTAN_AES_NI_H__ #include <botan/block_cipher.h> @@ -15,7 +15,7 @@ namespace Botan { /** * AES-128 using AES-NI */ -class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16> +class BOTAN_DLL AES_128_NI : public Block_Cipher_Fixed_Params<16, 16> { public: size_t parallelism() const { return 4; } @@ -25,9 +25,9 @@ class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16> void clear(); std::string name() const { return "AES-128"; } - BlockCipher* clone() const { return new AES_128_Intel; } + BlockCipher* clone() const { return new AES_128_NI; } - AES_128_Intel() : EK(44), DK(44) { } + AES_128_NI() : EK(44), DK(44) { } private: void key_schedule(const byte[], size_t); @@ -37,7 +37,7 @@ class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16> /** * AES-192 using AES-NI */ -class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24> +class BOTAN_DLL AES_192_NI : public Block_Cipher_Fixed_Params<16, 24> { public: size_t parallelism() const { return 4; } @@ -47,9 +47,9 @@ class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24> void clear(); std::string name() const { return "AES-192"; } - BlockCipher* clone() const { return new AES_192_Intel; } + BlockCipher* clone() const { return new AES_192_NI; } - AES_192_Intel() : EK(52), DK(52) { } + AES_192_NI() : EK(52), DK(52) { } private: void key_schedule(const byte[], size_t); @@ -59,7 +59,7 @@ class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24> /** * AES-256 using AES-NI */ -class BOTAN_DLL AES_256_Intel : public Block_Cipher_Fixed_Params<16, 32> +class BOTAN_DLL AES_256_NI : public Block_Cipher_Fixed_Params<16, 32> { public: size_t parallelism() const { return 4; } @@ -69,9 +69,9 @@ class BOTAN_DLL AES_256_Intel : public Block_Cipher_Fixed_Params<16, 32> void clear(); std::string name() const { return "AES-256"; } - BlockCipher* clone() const { return new AES_256_Intel; } + BlockCipher* clone() const { return new AES_256_NI; } - AES_256_Intel() : EK(60), DK(60) { } + AES_256_NI() : EK(60), DK(60) { } private: void key_schedule(const byte[], size_t); diff --git a/src/block/aes_intel/info.txt b/src/block/aes_ni/info.txt index 8bf0f07ee..597948fc3 100644 --- a/src/block/aes_intel/info.txt +++ b/src/block/aes_ni/info.txt @@ -1,4 +1,4 @@ -define AES_INTEL +define AES_NI load_on auto diff --git a/src/block/camellia/camellia.cpp b/src/block/camellia/camellia.cpp new file mode 100644 index 000000000..054558c35 --- /dev/null +++ b/src/block/camellia/camellia.cpp @@ -0,0 +1,311 @@ +/* +* Camellia +* (C) 2012 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/camellia.h> +#include <botan/loadstor.h> + +namespace Botan { + +namespace Camellia_F { + +u64bit F(u64bit v, u64bit K) + { + static const byte SBOX[256] = { + 0x70, 0x82, 0x2C, 0xEC, 0xB3, 0x27, 0xC0, 0xE5, 0xE4, 0x85, 0x57, + 0x35, 0xEA, 0x0C, 0xAE, 0x41, 0x23, 0xEF, 0x6B, 0x93, 0x45, 0x19, + 0xA5, 0x21, 0xED, 0x0E, 0x4F, 0x4E, 0x1D, 0x65, 0x92, 0xBD, 0x86, + 0xB8, 0xAF, 0x8F, 0x7C, 0xEB, 0x1F, 0xCE, 0x3E, 0x30, 0xDC, 0x5F, + 0x5E, 0xC5, 0x0B, 0x1A, 0xA6, 0xE1, 0x39, 0xCA, 0xD5, 0x47, 0x5D, + 0x3D, 0xD9, 0x01, 0x5A, 0xD6, 0x51, 0x56, 0x6C, 0x4D, 0x8B, 0x0D, + 0x9A, 0x66, 0xFB, 0xCC, 0xB0, 0x2D, 0x74, 0x12, 0x2B, 0x20, 0xF0, + 0xB1, 0x84, 0x99, 0xDF, 0x4C, 0xCB, 0xC2, 0x34, 0x7E, 0x76, 0x05, + 0x6D, 0xB7, 0xA9, 0x31, 0xD1, 0x17, 0x04, 0xD7, 0x14, 0x58, 0x3A, + 0x61, 0xDE, 0x1B, 0x11, 0x1C, 0x32, 0x0F, 0x9C, 0x16, 0x53, 0x18, + 0xF2, 0x22, 0xFE, 0x44, 0xCF, 0xB2, 0xC3, 0xB5, 0x7A, 0x91, 0x24, + 0x08, 0xE8, 0xA8, 0x60, 0xFC, 0x69, 0x50, 0xAA, 0xD0, 0xA0, 0x7D, + 0xA1, 0x89, 0x62, 0x97, 0x54, 0x5B, 0x1E, 0x95, 0xE0, 0xFF, 0x64, + 0xD2, 0x10, 0xC4, 0x00, 0x48, 0xA3, 0xF7, 0x75, 0xDB, 0x8A, 0x03, + 0xE6, 0xDA, 0x09, 0x3F, 0xDD, 0x94, 0x87, 0x5C, 0x83, 0x02, 0xCD, + 0x4A, 0x90, 0x33, 0x73, 0x67, 0xF6, 0xF3, 0x9D, 0x7F, 0xBF, 0xE2, + 0x52, 0x9B, 0xD8, 0x26, 0xC8, 0x37, 0xC6, 0x3B, 0x81, 0x96, 0x6F, + 0x4B, 0x13, 0xBE, 0x63, 0x2E, 0xE9, 0x79, 0xA7, 0x8C, 0x9F, 0x6E, + 0xBC, 0x8E, 0x29, 0xF5, 0xF9, 0xB6, 0x2F, 0xFD, 0xB4, 0x59, 0x78, + 0x98, 0x06, 0x6A, 0xE7, 0x46, 0x71, 0xBA, 0xD4, 0x25, 0xAB, 0x42, + 0x88, 0xA2, 0x8D, 0xFA, 0x72, 0x07, 0xB9, 0x55, 0xF8, 0xEE, 0xAC, + 0x0A, 0x36, 0x49, 0x2A, 0x68, 0x3C, 0x38, 0xF1, 0xA4, 0x40, 0x28, + 0xD3, 0x7B, 0xBB, 0xC9, 0x43, 0xC1, 0x15, 0xE3, 0xAD, 0xF4, 0x77, + 0xC7, 0x80, 0x9E }; + + const u64bit x = v ^ K; + + const byte t1 = SBOX[get_byte(0, x)]; + const byte t2 = rotate_left(SBOX[get_byte(1, x)], 1); + const byte t3 = rotate_left(SBOX[get_byte(2, x)], 7); + const byte t4 = SBOX[rotate_left(get_byte(3, x), 1)]; + const byte t5 = rotate_left(SBOX[get_byte(4, x)], 1); + const byte t6 = rotate_left(SBOX[get_byte(5, x)], 7); + const byte t7 = SBOX[rotate_left(get_byte(6, x), 1)]; + const byte t8 = SBOX[get_byte(7, x)]; + + const byte y1 = t1 ^ t3 ^ t4 ^ t6 ^ t7 ^ t8; + const byte y2 = t1 ^ t2 ^ t4 ^ t5 ^ t7 ^ t8; + const byte y3 = t1 ^ t2 ^ t3 ^ t5 ^ t6 ^ t8; + const byte y4 = t2 ^ t3 ^ t4 ^ t5 ^ t6 ^ t7; + const byte y5 = t1 ^ t2 ^ t6 ^ t7 ^ t8; + const byte y6 = t2 ^ t3 ^ t5 ^ t7 ^ t8; + const byte y7 = t3 ^ t4 ^ t5 ^ t6 ^ t8; + const byte y8 = t1 ^ t4 ^ t5 ^ t6 ^ t7; + + return make_u64bit(y1, y2, y3, y4, y5, y6, y7, y8); + } + +u64bit FL(u64bit v, u64bit K) + { + u32bit x1 = (v >> 32); + u32bit x2 = (v & 0xFFFFFFFF); + + const u32bit k1 = (K >> 32); + const u32bit k2 = (K & 0xFFFFFFFF); + + x2 ^= rotate_left(x1 & k1, 1); + x1 ^= (x2 | k2); + + return ((static_cast<u64bit>(x1) << 32) | x2); + } + +u64bit FLINV(u64bit v, u64bit K) + { + u32bit x1 = (v >> 32); + u32bit x2 = (v & 0xFFFFFFFF); + + const u32bit k1 = (K >> 32); + const u32bit k2 = (K & 0xFFFFFFFF); + + x1 ^= (x2 | k2); + x2 ^= rotate_left(x1 & k1, 1); + + return ((static_cast<u64bit>(x1) << 32) | x2); + } + +u64bit left_rot_hi(u64bit h, u64bit l, size_t shift) + { + return (h << shift) | ((l >> (64-shift))); + } + +u64bit left_rot_lo(u64bit h, u64bit l, size_t shift) + { + return (h >> (64-shift)) | (l << shift); + } + +} + +/* +* Camellia Encryption +*/ +void Camellia::encrypt_n(const byte in[], byte out[], size_t blocks) const + { + using namespace Camellia_F; + + for(size_t i = 0; i != blocks; ++i) + { + u64bit D1 = load_be<u64bit>(in, 0); + u64bit D2 = load_be<u64bit>(in, 1); + + const u64bit* K = &SK[0]; + + D1 ^= *K++; + D2 ^= *K++; + + while(true) + { + D2 ^= F(D1, *K++); + D1 ^= F(D2, *K++); + D2 ^= F(D1, *K++); + D1 ^= F(D2, *K++); + D2 ^= F(D1, *K++); + D1 ^= F(D2, *K++); + + if(K == &SK[SK.size()-2]) + break; + + D1 = FL (D1, *K++); + D2 = FLINV(D2, *K++); + } + + D2 ^= *K++; + D1 ^= *K++; + + store_be(out, D2, D1); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } + } + +/* +* Camellia Decryption +*/ +void Camellia::decrypt_n(const byte in[], byte out[], size_t blocks) const + { + using namespace Camellia_F; + + for(size_t i = 0; i != blocks; ++i) + { + u64bit D1 = load_be<u64bit>(in, 0); + u64bit D2 = load_be<u64bit>(in, 1); + + const u64bit* K = &SK[SK.size()-1]; + + D2 ^= *K--; + D1 ^= *K--; + + while(true) + { + D2 ^= F(D1, *K--); + D1 ^= F(D2, *K--); + D2 ^= F(D1, *K--); + D1 ^= F(D2, *K--); + D2 ^= F(D1, *K--); + D1 ^= F(D2, *K--); + + if(K == &SK[1]) + break; + + D1 = FL (D1, *K--); + D2 = FLINV(D2, *K--); + } + + D1 ^= *K--; + D2 ^= *K; + + store_be(out, D2, D1); + + in += BLOCK_SIZE; + out += BLOCK_SIZE; + } + } + +/* +* Camellia Key Schedule +*/ +void Camellia::key_schedule(const byte key[], size_t length) + { + using namespace Camellia_F; + + const u64bit Sigma1 = 0xA09E667F3BCC908B; + const u64bit Sigma2 = 0xB67AE8584CAA73B2; + const u64bit Sigma3 = 0xC6EF372FE94F82BE; + const u64bit Sigma4 = 0x54FF53A5F1D36F1C; + const u64bit Sigma5 = 0x10E527FADE682D1D; + const u64bit Sigma6 = 0xB05688C2B3E6C1FD; + + const u64bit KL_H = load_be<u64bit>(key, 0); + const u64bit KL_L = load_be<u64bit>(key, 1); + + const u64bit KR_H = (length >= 24) ? load_be<u64bit>(key, 2) : 0; + const u64bit KR_L = + (length == 32) ? load_be<u64bit>(key, 3) : ((length == 24) ? ~KR_H : 0); + + u64bit D1 = KL_H ^ KR_H; + u64bit D2 = KL_L ^ KR_L; + D2 ^= F(D1, Sigma1); + D1 ^= F(D2, Sigma2); + D1 ^= KL_H; + D2 ^= KL_L; + D2 ^= F(D1, Sigma3); + D1 ^= F(D2, Sigma4); + + const u64bit KA_H = D1; + const u64bit KA_L = D2; + + D1 = KA_H ^ KR_H; + D2 = KA_L ^ KR_L; + D2 ^= F(D1, Sigma5); + D1 ^= F(D2, Sigma6); + + const u64bit KB_H = D1; + const u64bit KB_L = D2; + + if(length == 16) + { + SK.resize(26); + + SK[ 0] = KL_H; + SK[ 1] = KL_L; + SK[ 2] = KA_H; + SK[ 3] = KA_L; + SK[ 4] = left_rot_hi(KL_H, KL_L, 15); + SK[ 5] = left_rot_lo(KL_H, KL_L, 15); + SK[ 6] = left_rot_hi(KA_H, KA_L, 15); + SK[ 7] = left_rot_lo(KA_H, KA_L, 15); + SK[ 8] = left_rot_hi(KA_H, KA_L, 30); + SK[ 9] = left_rot_lo(KA_H, KA_L, 30); + SK[10] = left_rot_hi(KL_H, KL_L, 45); + SK[11] = left_rot_lo(KL_H, KL_L, 45); + SK[12] = left_rot_hi(KA_H, KA_L, 45); + SK[13] = left_rot_lo(KL_H, KL_L, 60); + SK[14] = left_rot_hi(KA_H, KA_L, 60); + SK[15] = left_rot_lo(KA_H, KA_L, 60); + SK[16] = left_rot_lo(KL_H, KL_L, 77-64); + SK[17] = left_rot_hi(KL_H, KL_L, 77-64); + SK[18] = left_rot_lo(KL_H, KL_L, 94-64); + SK[19] = left_rot_hi(KL_H, KL_L, 94-64); + SK[20] = left_rot_lo(KA_H, KA_L, 94-64); + SK[21] = left_rot_hi(KA_H, KA_L, 94-64); + SK[22] = left_rot_lo(KL_H, KL_L, 111-64); + SK[23] = left_rot_hi(KL_H, KL_L, 111-64); + SK[24] = left_rot_lo(KA_H, KA_L, 111-64); + SK[25] = left_rot_hi(KA_H, KA_L, 111-64); + } + else + { + SK.resize(34); + + SK[ 0] = KL_H; + SK[ 1] = KL_L; + SK[ 2] = KB_H; + SK[ 3] = KB_L; + + SK[ 4] = left_rot_hi(KR_H, KR_L, 15); + SK[ 5] = left_rot_lo(KR_H, KR_L, 15); + SK[ 6] = left_rot_hi(KA_H, KA_L, 15); + SK[ 7] = left_rot_lo(KA_H, KA_L, 15); + + SK[ 8] = left_rot_hi(KR_H, KR_L, 30); + SK[ 9] = left_rot_lo(KR_H, KR_L, 30); + SK[10] = left_rot_hi(KB_H, KB_L, 30); + SK[11] = left_rot_lo(KB_H, KB_L, 30); + + SK[12] = left_rot_hi(KL_H, KL_L, 45); + SK[13] = left_rot_lo(KL_H, KL_L, 45); + SK[14] = left_rot_hi(KA_H, KA_L, 45); + SK[15] = left_rot_lo(KA_H, KA_L, 45); + + SK[16] = left_rot_hi(KL_H, KL_L, 60); + SK[17] = left_rot_lo(KL_H, KL_L, 60); + SK[18] = left_rot_hi(KR_H, KR_L, 60); + SK[19] = left_rot_lo(KR_H, KR_L, 60); + SK[20] = left_rot_hi(KB_H, KB_L, 60); + SK[21] = left_rot_lo(KB_H, KB_L, 60); + + SK[22] = left_rot_lo(KL_H, KL_L, 77-64); + SK[23] = left_rot_hi(KL_H, KL_L, 77-64); + SK[24] = left_rot_lo(KA_H, KA_L, 77-64); + SK[25] = left_rot_hi(KA_H, KA_L, 77-64); + + SK[26] = left_rot_lo(KR_H, KR_L, 94-64); + SK[27] = left_rot_hi(KR_H, KR_L, 94-64); + SK[28] = left_rot_lo(KA_H, KA_L, 94-64); + SK[29] = left_rot_hi(KA_H, KA_L, 94-64); + SK[30] = left_rot_lo(KL_H, KL_L, 111-64); + SK[31] = left_rot_hi(KL_H, KL_L, 111-64); + SK[32] = left_rot_lo(KB_H, KB_L, 111-64); + SK[33] = left_rot_hi(KB_H, KB_L, 111-64); + } + } + +} diff --git a/src/block/camellia/camellia.h b/src/block/camellia/camellia.h new file mode 100644 index 000000000..aaf3ad9e3 --- /dev/null +++ b/src/block/camellia/camellia.h @@ -0,0 +1,35 @@ +/* +* Camellia +* (C) 2012 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CAMELLIA_H__ +#define BOTAN_CAMELLIA_H__ + +#include <botan/block_cipher.h> + +namespace Botan { + +/** +* Camellia +*/ +class BOTAN_DLL Camellia : public Block_Cipher_Fixed_Params<16, 16, 32, 8> + { + public: + void encrypt_n(const byte in[], byte out[], size_t blocks) const; + void decrypt_n(const byte in[], byte out[], size_t blocks) const; + + void clear() { SK.clear(); } + std::string name() const { return "Camellia"; } + BlockCipher* clone() const { return new Camellia; } + private: + void key_schedule(const byte key[], size_t length); + + SecureVector<u64bit> SK; + }; + +} + +#endif diff --git a/src/block/camellia/info.txt b/src/block/camellia/info.txt new file mode 100644 index 000000000..cdb7b3d25 --- /dev/null +++ b/src/block/camellia/info.txt @@ -0,0 +1 @@ +define CAMELLIA diff --git a/src/block/gost_28147/gost_28147.cpp b/src/block/gost_28147/gost_28147.cpp index 07f3359cd..d4a9faa40 100644 --- a/src/block/gost_28147/gost_28147.cpp +++ b/src/block/gost_28147/gost_28147.cpp @@ -1,6 +1,6 @@ /* * GOST 28147-89 -* (C) 1999-2009 Jack Lloyd +* (C) 1999-2009,2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -58,12 +58,31 @@ GOST_28147_89::GOST_28147_89(const GOST_28147_89_Params& param) : for(size_t i = 0; i != 4; ++i) for(size_t j = 0; j != 256; ++j) { - u32bit T = (param.sbox_entry(2*i , j % 16)) | - (param.sbox_entry(2*i+1, j / 16) << 4); + const u32bit T = (param.sbox_entry(2*i , j % 16)) | + (param.sbox_entry(2*i+1, j / 16) << 4); SBOX[256*i+j] = rotate_left(T, (11+8*i) % 32); } } +std::string GOST_28147_89::name() const + { + /* + 'Guess' the right name for the sbox on the basis of the values. + This would need to be updated if support for other sbox parameters + is added. Preferably, we would just store the string value in the + constructor, but can't break binary compat. + */ + std::string sbox_name = ""; + if(SBOX[0] == 0x00072000) + sbox_name = "R3411_94_TestParam"; + else if(SBOX[0] == 0x0002D000) + sbox_name = "R3411_CryptoPro"; + else + throw Internal_Error("GOST-28147 unrecognized sbox value"); + + return "GOST-28147-89(" + sbox_name + ")"; + } + /* * Two rounds of GOST */ diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h index 75ba74c44..bc26da774 100644 --- a/src/block/gost_28147/gost_28147.h +++ b/src/block/gost_28147/gost_28147.h @@ -57,7 +57,7 @@ class BOTAN_DLL GOST_28147_89 : public Block_Cipher_Fixed_Params<8, 32> void clear() { zeroise(EK); } - std::string name() const { return "GOST-28147-89"; } + std::string name() const; BlockCipher* clone() const { return new GOST_28147_89(SBOX); } /** diff --git a/src/block/idea_sse2/idea_sse2.cpp b/src/block/idea_sse2/idea_sse2.cpp index b92f51ac3..70698560d 100644 --- a/src/block/idea_sse2/idea_sse2.cpp +++ b/src/block/idea_sse2/idea_sse2.cpp @@ -16,7 +16,6 @@ inline __m128i mul(__m128i X, u16bit K_16) { const __m128i zeros = _mm_set1_epi16(0); const __m128i ones = _mm_set1_epi16(1); - const __m128i high_bit = _mm_set1_epi16(-32767); // 0x8000 const __m128i K = _mm_set1_epi16(K_16); @@ -29,10 +28,9 @@ inline __m128i mul(__m128i X, u16bit K_16) __m128i T = _mm_sub_epi16(mul_lo, mul_hi); // Unsigned compare; cmp = 1 if mul_lo < mul_hi else 0 - const __m128i cmp = _mm_srli_epi16(_mm_cmpgt_epi16( - _mm_add_epi16(mul_hi, high_bit), - _mm_add_epi16(mul_lo, high_bit)), - 15); + const __m128i subs = _mm_subs_epu16(mul_hi, mul_lo); + const __m128i cmp = _mm_min_epu8( + _mm_or_si128(subs, _mm_srli_epi16(subs, 8)), ones); T = _mm_add_epi16(T, cmp); diff --git a/src/block/noekeon_simd/info.txt b/src/block/noekeon_simd/info.txt index b73954cff..deac80702 100644 --- a/src/block/noekeon_simd/info.txt +++ b/src/block/noekeon_simd/info.txt @@ -2,6 +2,6 @@ define NOEKEON_SIMD <requires> noekeon -simd_32 +simd simd_engine </requires> diff --git a/src/block/serpent_simd/info.txt b/src/block/serpent_simd/info.txt index b3bf34972..cd1a0dc7e 100644 --- a/src/block/serpent_simd/info.txt +++ b/src/block/serpent_simd/info.txt @@ -2,7 +2,7 @@ define SERPENT_SIMD <requires> serpent -simd_32 +simd simd_engine </requires> @@ -13,7 +13,3 @@ serp_simd.cpp <header:public> serp_simd.h </header:public> - -<header:internal> -serp_simd_sbox.h -</header:internal> diff --git a/src/block/serpent_simd/serp_simd.cpp b/src/block/serpent_simd/serp_simd.cpp index babe68d40..2b5e429fc 100644 --- a/src/block/serpent_simd/serp_simd.cpp +++ b/src/block/serpent_simd/serp_simd.cpp @@ -6,7 +6,6 @@ */ #include <botan/serp_simd.h> -#include <botan/internal/serp_simd_sbox.h> #include <botan/internal/simd_32.h> #include <botan/loadstor.h> @@ -14,6 +13,420 @@ namespace Botan { namespace { +#define SBoxE1(B0, B1, B2, B3) \ + do { \ + B3 ^= B0; \ + SIMD_32 B4 = B1; \ + B1 &= B3; \ + B4 ^= B2; \ + B1 ^= B0; \ + B0 |= B3; \ + B0 ^= B4; \ + B4 ^= B3; \ + B3 ^= B2; \ + B2 |= B1; \ + B2 ^= B4; \ + B4 = ~B4; \ + B4 |= B1; \ + B1 ^= B3; \ + B1 ^= B4; \ + B3 |= B0; \ + B1 ^= B3; \ + B4 ^= B3; \ + B3 = B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE2(B0, B1, B2, B3) \ + do { \ + B0 = ~B0; \ + B2 = ~B2; \ + SIMD_32 B4 = B0; \ + B0 &= B1; \ + B2 ^= B0; \ + B0 |= B3; \ + B3 ^= B2; \ + B1 ^= B0; \ + B0 ^= B4; \ + B4 |= B1; \ + B1 ^= B3; \ + B2 |= B0; \ + B2 &= B4; \ + B0 ^= B1; \ + B1 &= B2; \ + B1 ^= B0; \ + B0 &= B2; \ + B4 ^= B0; \ + B0 = B2; \ + B2 = B3; \ + B3 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE3(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B0; \ + B0 &= B2; \ + B0 ^= B3; \ + B2 ^= B1; \ + B2 ^= B0; \ + B3 |= B4; \ + B3 ^= B1; \ + B4 ^= B2; \ + B1 = B3; \ + B3 |= B4; \ + B3 ^= B0; \ + B0 &= B1; \ + B4 ^= B0; \ + B1 ^= B3; \ + B1 ^= B4; \ + B0 = B2; \ + B2 = B1; \ + B1 = B3; \ + B3 = ~B4; \ + } while(0); + +#define SBoxE4(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B0; \ + B0 |= B3; \ + B3 ^= B1; \ + B1 &= B4; \ + B4 ^= B2; \ + B2 ^= B3; \ + B3 &= B0; \ + B4 |= B1; \ + B3 ^= B4; \ + B0 ^= B1; \ + B4 &= B0; \ + B1 ^= B3; \ + B4 ^= B2; \ + B1 |= B0; \ + B1 ^= B2; \ + B0 ^= B3; \ + B2 = B1; \ + B1 |= B3; \ + B0 ^= B1; \ + B1 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxE5(B0, B1, B2, B3) \ + do { \ + B1 ^= B3; \ + B3 = ~B3; \ + B2 ^= B3; \ + B3 ^= B0; \ + SIMD_32 B4 = B1; \ + B1 &= B3; \ + B1 ^= B2; \ + B4 ^= B3; \ + B0 ^= B4; \ + B2 &= B4; \ + B2 ^= B0; \ + B0 &= B1; \ + B3 ^= B0; \ + B4 |= B1; \ + B4 ^= B0; \ + B0 |= B3; \ + B0 ^= B2; \ + B2 &= B3; \ + B0 = ~B0; \ + B4 ^= B2; \ + B2 = B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE6(B0, B1, B2, B3) \ + do { \ + B0 ^= B1; \ + B1 ^= B3; \ + B3 = ~B3; \ + SIMD_32 B4 = B1; \ + B1 &= B0; \ + B2 ^= B3; \ + B1 ^= B2; \ + B2 |= B4; \ + B4 ^= B3; \ + B3 &= B1; \ + B3 ^= B0; \ + B4 ^= B1; \ + B4 ^= B2; \ + B2 ^= B0; \ + B0 &= B3; \ + B2 = ~B2; \ + B0 ^= B4; \ + B4 |= B3; \ + B4 ^= B2; \ + B2 = B0; \ + B0 = B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxE7(B0, B1, B2, B3) \ + do { \ + B2 = ~B2; \ + SIMD_32 B4 = B3; \ + B3 &= B0; \ + B0 ^= B4; \ + B3 ^= B2; \ + B2 |= B4; \ + B1 ^= B3; \ + B2 ^= B0; \ + B0 |= B1; \ + B2 ^= B1; \ + B4 ^= B0; \ + B0 |= B3; \ + B0 ^= B2; \ + B4 ^= B3; \ + B4 ^= B0; \ + B3 = ~B3; \ + B2 &= B4; \ + B3 ^= B2; \ + B2 = B4; \ + } while(0); + +#define SBoxE8(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B1; \ + B1 |= B2; \ + B1 ^= B3; \ + B4 ^= B2; \ + B2 ^= B1; \ + B3 |= B4; \ + B3 &= B0; \ + B4 ^= B2; \ + B3 ^= B1; \ + B1 |= B4; \ + B1 ^= B0; \ + B0 |= B4; \ + B0 ^= B2; \ + B1 ^= B4; \ + B2 ^= B1; \ + B1 &= B0; \ + B1 ^= B4; \ + B2 = ~B2; \ + B2 |= B0; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B3; \ + B3 = B0; \ + B0 = B4; \ + } while(0); + +#define SBoxD1(B0, B1, B2, B3) \ + do { \ + B2 = ~B2; \ + SIMD_32 B4 = B1; \ + B1 |= B0; \ + B4 = ~B4; \ + B1 ^= B2; \ + B2 |= B4; \ + B1 ^= B3; \ + B0 ^= B4; \ + B2 ^= B0; \ + B0 &= B3; \ + B4 ^= B0; \ + B0 |= B1; \ + B0 ^= B2; \ + B3 ^= B4; \ + B2 ^= B1; \ + B3 ^= B0; \ + B3 ^= B1; \ + B2 &= B3; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxD2(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B1; \ + B1 ^= B3; \ + B3 &= B1; \ + B4 ^= B2; \ + B3 ^= B0; \ + B0 |= B1; \ + B2 ^= B3; \ + B0 ^= B4; \ + B0 |= B2; \ + B1 ^= B3; \ + B0 ^= B1; \ + B1 |= B3; \ + B1 ^= B0; \ + B4 = ~B4; \ + B4 ^= B1; \ + B1 |= B0; \ + B1 ^= B0; \ + B1 |= B4; \ + B3 ^= B1; \ + B1 = B0; \ + B0 = B4; \ + B4 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD3(B0, B1, B2, B3) \ + do { \ + B2 ^= B3; \ + B3 ^= B0; \ + SIMD_32 B4 = B3; \ + B3 &= B2; \ + B3 ^= B1; \ + B1 |= B2; \ + B1 ^= B4; \ + B4 &= B3; \ + B2 ^= B3; \ + B4 &= B0; \ + B4 ^= B2; \ + B2 &= B1; \ + B2 |= B0; \ + B3 = ~B3; \ + B2 ^= B3; \ + B0 ^= B3; \ + B0 &= B1; \ + B3 ^= B4; \ + B3 ^= B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxD4(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 ^= B1; \ + B0 ^= B2; \ + B4 &= B2; \ + B4 ^= B0; \ + B0 &= B1; \ + B1 ^= B3; \ + B3 |= B4; \ + B2 ^= B3; \ + B0 ^= B3; \ + B1 ^= B4; \ + B3 &= B2; \ + B3 ^= B1; \ + B1 ^= B0; \ + B1 |= B2; \ + B0 ^= B3; \ + B1 ^= B4; \ + B0 ^= B1; \ + B4 = B0; \ + B0 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD5(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 &= B3; \ + B2 ^= B1; \ + B1 |= B3; \ + B1 &= B0; \ + B4 ^= B2; \ + B4 ^= B1; \ + B1 &= B2; \ + B0 = ~B0; \ + B3 ^= B4; \ + B1 ^= B3; \ + B3 &= B0; \ + B3 ^= B2; \ + B0 ^= B1; \ + B2 &= B0; \ + B3 ^= B0; \ + B2 ^= B4; \ + B2 |= B3; \ + B3 ^= B0; \ + B2 ^= B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD6(B0, B1, B2, B3) \ + do { \ + B1 = ~B1; \ + SIMD_32 B4 = B3; \ + B2 ^= B1; \ + B3 |= B0; \ + B3 ^= B2; \ + B2 |= B1; \ + B2 &= B0; \ + B4 ^= B3; \ + B2 ^= B4; \ + B4 |= B0; \ + B4 ^= B1; \ + B1 &= B2; \ + B1 ^= B3; \ + B4 ^= B2; \ + B3 &= B4; \ + B4 ^= B1; \ + B3 ^= B4; \ + B4 = ~B4; \ + B3 ^= B0; \ + B0 = B1; \ + B1 = B4; \ + B4 = B3; \ + B3 = B2; \ + B2 = B4; \ + } while(0); + +#define SBoxD7(B0, B1, B2, B3) \ + do { \ + B0 ^= B2; \ + SIMD_32 B4 = B2; \ + B2 &= B0; \ + B4 ^= B3; \ + B2 = ~B2; \ + B3 ^= B1; \ + B2 ^= B3; \ + B4 |= B0; \ + B0 ^= B2; \ + B3 ^= B4; \ + B4 ^= B1; \ + B1 &= B3; \ + B1 ^= B0; \ + B0 ^= B3; \ + B0 |= B2; \ + B3 ^= B1; \ + B4 ^= B0; \ + B0 = B1; \ + B1 = B2; \ + B2 = B4; \ + } while(0); + +#define SBoxD8(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 ^= B0; \ + B0 &= B3; \ + B4 |= B3; \ + B2 = ~B2; \ + B3 ^= B1; \ + B1 |= B0; \ + B0 ^= B2; \ + B2 &= B4; \ + B3 &= B4; \ + B1 ^= B2; \ + B2 ^= B0; \ + B0 |= B2; \ + B4 ^= B1; \ + B0 ^= B3; \ + B3 ^= B4; \ + B4 |= B0; \ + B3 ^= B2; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B0; \ + B0 = B3; \ + B3 = B4; \ + } while(0); + #define key_xor(round, B0, B1, B2, B3) \ do { \ B0 ^= SIMD_32(keys[4*round ]); \ @@ -175,6 +588,24 @@ void serpent_decrypt_4(const byte in[64], #undef transform #undef i_transform +#undef SBoxE1 +#undef SBoxE2 +#undef SBoxE3 +#undef SBoxE4 +#undef SBoxE5 +#undef SBoxE6 +#undef SBoxE7 +#undef SBoxE8 + +#undef SBoxD1 +#undef SBoxD2 +#undef SBoxD3 +#undef SBoxD4 +#undef SBoxD5 +#undef SBoxD6 +#undef SBoxD7 +#undef SBoxD8 + /* * Serpent Encryption */ diff --git a/src/block/serpent_simd/serp_simd_sbox.h b/src/block/serpent_simd/serp_simd_sbox.h deleted file mode 100644 index 71eca19e5..000000000 --- a/src/block/serpent_simd/serp_simd_sbox.h +++ /dev/null @@ -1,425 +0,0 @@ -/* -* Serpent Sboxes in SIMD form -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SERPENT_SIMD_SBOXES_H__ -#define BOTAN_SERPENT_SIMD_SBOXES_H__ - -#define SBoxE1(B0, B1, B2, B3) \ - do { \ - B3 ^= B0; \ - SIMD_32 B4 = B1; \ - B1 &= B3; \ - B4 ^= B2; \ - B1 ^= B0; \ - B0 |= B3; \ - B0 ^= B4; \ - B4 ^= B3; \ - B3 ^= B2; \ - B2 |= B1; \ - B2 ^= B4; \ - B4 = ~B4; \ - B4 |= B1; \ - B1 ^= B3; \ - B1 ^= B4; \ - B3 |= B0; \ - B1 ^= B3; \ - B4 ^= B3; \ - B3 = B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE2(B0, B1, B2, B3) \ - do { \ - B0 = ~B0; \ - B2 = ~B2; \ - SIMD_32 B4 = B0; \ - B0 &= B1; \ - B2 ^= B0; \ - B0 |= B3; \ - B3 ^= B2; \ - B1 ^= B0; \ - B0 ^= B4; \ - B4 |= B1; \ - B1 ^= B3; \ - B2 |= B0; \ - B2 &= B4; \ - B0 ^= B1; \ - B1 &= B2; \ - B1 ^= B0; \ - B0 &= B2; \ - B4 ^= B0; \ - B0 = B2; \ - B2 = B3; \ - B3 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE3(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B0; \ - B0 &= B2; \ - B0 ^= B3; \ - B2 ^= B1; \ - B2 ^= B0; \ - B3 |= B4; \ - B3 ^= B1; \ - B4 ^= B2; \ - B1 = B3; \ - B3 |= B4; \ - B3 ^= B0; \ - B0 &= B1; \ - B4 ^= B0; \ - B1 ^= B3; \ - B1 ^= B4; \ - B0 = B2; \ - B2 = B1; \ - B1 = B3; \ - B3 = ~B4; \ - } while(0); - -#define SBoxE4(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B0; \ - B0 |= B3; \ - B3 ^= B1; \ - B1 &= B4; \ - B4 ^= B2; \ - B2 ^= B3; \ - B3 &= B0; \ - B4 |= B1; \ - B3 ^= B4; \ - B0 ^= B1; \ - B4 &= B0; \ - B1 ^= B3; \ - B4 ^= B2; \ - B1 |= B0; \ - B1 ^= B2; \ - B0 ^= B3; \ - B2 = B1; \ - B1 |= B3; \ - B0 ^= B1; \ - B1 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxE5(B0, B1, B2, B3) \ - do { \ - B1 ^= B3; \ - B3 = ~B3; \ - B2 ^= B3; \ - B3 ^= B0; \ - SIMD_32 B4 = B1; \ - B1 &= B3; \ - B1 ^= B2; \ - B4 ^= B3; \ - B0 ^= B4; \ - B2 &= B4; \ - B2 ^= B0; \ - B0 &= B1; \ - B3 ^= B0; \ - B4 |= B1; \ - B4 ^= B0; \ - B0 |= B3; \ - B0 ^= B2; \ - B2 &= B3; \ - B0 = ~B0; \ - B4 ^= B2; \ - B2 = B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE6(B0, B1, B2, B3) \ - do { \ - B0 ^= B1; \ - B1 ^= B3; \ - B3 = ~B3; \ - SIMD_32 B4 = B1; \ - B1 &= B0; \ - B2 ^= B3; \ - B1 ^= B2; \ - B2 |= B4; \ - B4 ^= B3; \ - B3 &= B1; \ - B3 ^= B0; \ - B4 ^= B1; \ - B4 ^= B2; \ - B2 ^= B0; \ - B0 &= B3; \ - B2 = ~B2; \ - B0 ^= B4; \ - B4 |= B3; \ - B4 ^= B2; \ - B2 = B0; \ - B0 = B1; \ - B1 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxE7(B0, B1, B2, B3) \ - do { \ - B2 = ~B2; \ - SIMD_32 B4 = B3; \ - B3 &= B0; \ - B0 ^= B4; \ - B3 ^= B2; \ - B2 |= B4; \ - B1 ^= B3; \ - B2 ^= B0; \ - B0 |= B1; \ - B2 ^= B1; \ - B4 ^= B0; \ - B0 |= B3; \ - B0 ^= B2; \ - B4 ^= B3; \ - B4 ^= B0; \ - B3 = ~B3; \ - B2 &= B4; \ - B3 ^= B2; \ - B2 = B4; \ - } while(0); - -#define SBoxE8(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B1; \ - B1 |= B2; \ - B1 ^= B3; \ - B4 ^= B2; \ - B2 ^= B1; \ - B3 |= B4; \ - B3 &= B0; \ - B4 ^= B2; \ - B3 ^= B1; \ - B1 |= B4; \ - B1 ^= B0; \ - B0 |= B4; \ - B0 ^= B2; \ - B1 ^= B4; \ - B2 ^= B1; \ - B1 &= B0; \ - B1 ^= B4; \ - B2 = ~B2; \ - B2 |= B0; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B3; \ - B3 = B0; \ - B0 = B4; \ - } while(0); - -#define SBoxD1(B0, B1, B2, B3) \ - do { \ - B2 = ~B2; \ - SIMD_32 B4 = B1; \ - B1 |= B0; \ - B4 = ~B4; \ - B1 ^= B2; \ - B2 |= B4; \ - B1 ^= B3; \ - B0 ^= B4; \ - B2 ^= B0; \ - B0 &= B3; \ - B4 ^= B0; \ - B0 |= B1; \ - B0 ^= B2; \ - B3 ^= B4; \ - B2 ^= B1; \ - B3 ^= B0; \ - B3 ^= B1; \ - B2 &= B3; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxD2(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B1; \ - B1 ^= B3; \ - B3 &= B1; \ - B4 ^= B2; \ - B3 ^= B0; \ - B0 |= B1; \ - B2 ^= B3; \ - B0 ^= B4; \ - B0 |= B2; \ - B1 ^= B3; \ - B0 ^= B1; \ - B1 |= B3; \ - B1 ^= B0; \ - B4 = ~B4; \ - B4 ^= B1; \ - B1 |= B0; \ - B1 ^= B0; \ - B1 |= B4; \ - B3 ^= B1; \ - B1 = B0; \ - B0 = B4; \ - B4 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD3(B0, B1, B2, B3) \ - do { \ - B2 ^= B3; \ - B3 ^= B0; \ - SIMD_32 B4 = B3; \ - B3 &= B2; \ - B3 ^= B1; \ - B1 |= B2; \ - B1 ^= B4; \ - B4 &= B3; \ - B2 ^= B3; \ - B4 &= B0; \ - B4 ^= B2; \ - B2 &= B1; \ - B2 |= B0; \ - B3 = ~B3; \ - B2 ^= B3; \ - B0 ^= B3; \ - B0 &= B1; \ - B3 ^= B4; \ - B3 ^= B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxD4(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 ^= B1; \ - B0 ^= B2; \ - B4 &= B2; \ - B4 ^= B0; \ - B0 &= B1; \ - B1 ^= B3; \ - B3 |= B4; \ - B2 ^= B3; \ - B0 ^= B3; \ - B1 ^= B4; \ - B3 &= B2; \ - B3 ^= B1; \ - B1 ^= B0; \ - B1 |= B2; \ - B0 ^= B3; \ - B1 ^= B4; \ - B0 ^= B1; \ - B4 = B0; \ - B0 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD5(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 &= B3; \ - B2 ^= B1; \ - B1 |= B3; \ - B1 &= B0; \ - B4 ^= B2; \ - B4 ^= B1; \ - B1 &= B2; \ - B0 = ~B0; \ - B3 ^= B4; \ - B1 ^= B3; \ - B3 &= B0; \ - B3 ^= B2; \ - B0 ^= B1; \ - B2 &= B0; \ - B3 ^= B0; \ - B2 ^= B4; \ - B2 |= B3; \ - B3 ^= B0; \ - B2 ^= B1; \ - B1 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD6(B0, B1, B2, B3) \ - do { \ - B1 = ~B1; \ - SIMD_32 B4 = B3; \ - B2 ^= B1; \ - B3 |= B0; \ - B3 ^= B2; \ - B2 |= B1; \ - B2 &= B0; \ - B4 ^= B3; \ - B2 ^= B4; \ - B4 |= B0; \ - B4 ^= B1; \ - B1 &= B2; \ - B1 ^= B3; \ - B4 ^= B2; \ - B3 &= B4; \ - B4 ^= B1; \ - B3 ^= B4; \ - B4 = ~B4; \ - B3 ^= B0; \ - B0 = B1; \ - B1 = B4; \ - B4 = B3; \ - B3 = B2; \ - B2 = B4; \ - } while(0); - -#define SBoxD7(B0, B1, B2, B3) \ - do { \ - B0 ^= B2; \ - SIMD_32 B4 = B2; \ - B2 &= B0; \ - B4 ^= B3; \ - B2 = ~B2; \ - B3 ^= B1; \ - B2 ^= B3; \ - B4 |= B0; \ - B0 ^= B2; \ - B3 ^= B4; \ - B4 ^= B1; \ - B1 &= B3; \ - B1 ^= B0; \ - B0 ^= B3; \ - B0 |= B2; \ - B3 ^= B1; \ - B4 ^= B0; \ - B0 = B1; \ - B1 = B2; \ - B2 = B4; \ - } while(0); - -#define SBoxD8(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 ^= B0; \ - B0 &= B3; \ - B4 |= B3; \ - B2 = ~B2; \ - B3 ^= B1; \ - B1 |= B0; \ - B0 ^= B2; \ - B2 &= B4; \ - B3 &= B4; \ - B1 ^= B2; \ - B2 ^= B0; \ - B0 |= B2; \ - B4 ^= B1; \ - B0 ^= B3; \ - B3 ^= B4; \ - B4 |= B0; \ - B3 ^= B2; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B0; \ - B0 = B3; \ - B3 = B4; \ - } while(0); - -#endif diff --git a/src/block/xtea_simd/info.txt b/src/block/xtea_simd/info.txt index 5a8445b35..c16bfa2fa 100644 --- a/src/block/xtea_simd/info.txt +++ b/src/block/xtea_simd/info.txt @@ -2,6 +2,6 @@ define XTEA_SIMD <requires> xtea -simd_32 +simd simd_engine </requires> diff --git a/src/build-data/arch/arm.txt b/src/build-data/arch/arm.txt index 14f88c362..b822fe130 100644 --- a/src/build-data/arch/arm.txt +++ b/src/build-data/arch/arm.txt @@ -2,6 +2,11 @@ endian little family arm +<aliases> +armel # For Debian +armhf # For Debian +</aliases> + <submodels> armv2 armv2a diff --git a/src/build-data/arch/hitachi-sh.txt b/src/build-data/arch/hitachi-sh.txt deleted file mode 100644 index bab84b48f..000000000 --- a/src/build-data/arch/hitachi-sh.txt +++ /dev/null @@ -1,7 +0,0 @@ -<submodels> -hitachi-sh1 -hitachi-sh2 -hitachi-sh3 -hitachi-sh3e -hitachi-sh4 -</submodels> diff --git a/src/build-data/arch/ppc.txt b/src/build-data/arch/ppc32.txt index dc3ea7829..e33c8ff24 100644 --- a/src/build-data/arch/ppc.txt +++ b/src/build-data/arch/ppc32.txt @@ -5,13 +5,9 @@ family ppc <aliases> powerpc +ppc </aliases> -<submodel_aliases> -g3 -> ppc740 -g4 -> ppc7450 -</submodel_aliases> - <submodels> ppc601 ppc603 @@ -20,8 +16,15 @@ ppc740 ppc750 ppc7400 ppc7450 +e500v2 </submodels> +<submodel_aliases> +g3 -> ppc740 +g4 -> ppc7450 +powerpcspe -> e500v2 # for Debian +</submodel_aliases> + <isa_extn> altivec:ppc7400,ppc7450 </isa_extn> diff --git a/src/build-data/arch/ppc64.txt b/src/build-data/arch/ppc64.txt index 7a2e6b6b3..954d9181e 100644 --- a/src/build-data/arch/ppc64.txt +++ b/src/build-data/arch/ppc64.txt @@ -11,7 +11,6 @@ g5 -> ppc970 </submodel_aliases> <submodels> -rs64a ppc970 power3 power4 diff --git a/src/build-data/arch/sparc32.txt b/src/build-data/arch/sparc32.txt index fc015e520..69f3479aa 100644 --- a/src/build-data/arch/sparc32.txt +++ b/src/build-data/arch/sparc32.txt @@ -26,4 +26,6 @@ sparcv9 -> sparc32-v9 sparc-v7 -> sparc32-v7 sparc-v8 -> sparc32-v8 sparc-v9 -> sparc32-v9 + +sun4u -> sparc32-v9 </submodel_aliases> diff --git a/src/build-data/arch/sparc64.txt b/src/build-data/arch/sparc64.txt index 7344fa390..3a6acd6c3 100644 --- a/src/build-data/arch/sparc64.txt +++ b/src/build-data/arch/sparc64.txt @@ -1,13 +1,11 @@ family sparc -<aliases> -sun4u -</aliases> - <submodels> ultrasparc ultrasparc3 +niagra +niagra2 </submodels> <submodel_aliases> diff --git a/src/build-data/arch/superh.txt b/src/build-data/arch/superh.txt new file mode 100644 index 000000000..c7dc09861 --- /dev/null +++ b/src/build-data/arch/superh.txt @@ -0,0 +1,5 @@ +<submodels> +sh2 +sh3 +sh4 +</submodels> diff --git a/src/build-data/arch/x86_32.txt b/src/build-data/arch/x86_32.txt index 9289f1b2e..482a53057 100644 --- a/src/build-data/arch/x86_32.txt +++ b/src/build-data/arch/x86_32.txt @@ -25,7 +25,7 @@ pentium-m prescott k6 athlon -atom +atom32 </submodels> <submodel_aliases> @@ -62,7 +62,7 @@ intelcput2700 -> prescott </submodel_aliases> <isa_extn> -sse2:pentium4,prescott,pentium-m,atom -ssse3:atom -movbe:atom +sse2:pentium4,prescott,pentium-m,atom32 +ssse3:atom32 +movbe:atom32 </isa_extn> diff --git a/src/build-data/arch/x86_64.txt b/src/build-data/arch/x86_64.txt index 59e48329a..922daa104 100644 --- a/src/build-data/arch/x86_64.txt +++ b/src/build-data/arch/x86_64.txt @@ -13,10 +13,12 @@ x64 <submodels> k8 k10 +atom nocona core2 nehalem westmere +sandybridge </submodels> <submodel_aliases> @@ -36,6 +38,6 @@ corei7cpu860 -> nehalem <isa_extn> sse2:all -ssse3:core2,nehalem,westmere -aes-ni:westmere +ssse3:core2,nehalem,westmere,atom,sandybridge +aes-ni:westmere,sandybridge </isa_extn> diff --git a/src/build-data/botan-config.in b/src/build-data/botan-config.in index f3fa3db94..6780c12b8 100644 --- a/src/build-data/botan-config.in +++ b/src/build-data/botan-config.in @@ -2,7 +2,7 @@ # For normal builds: guess_prefix=`dirname \`dirname $0\`` -includedir=%{includedir} +includedir=%{includedir}/botan-%{version_major}.%{version_minor} libdir=%{libdir} # For workspace builds: @@ -54,9 +54,9 @@ while test $# -gt 0; do --libs) if [ $prefix != "/usr" -a $prefix != "/usr/local" ] then - echo -L$prefix/$libdir -lbotan %{link_to} + echo -L$prefix/$libdir -lbotan-%{version_major}.%{version_minor} %{link_to} else - echo -lbotan %{link_to} + echo -lbotan-%{version_major}.%{version_minor} %{link_to} fi ;; *) diff --git a/src/build-data/botan.pc.in b/src/build-data/botan.pc.in index 70ed65d70..301f84600 100644 --- a/src/build-data/botan.pc.in +++ b/src/build-data/botan.pc.in @@ -1,12 +1,12 @@ prefix=%{prefix} exec_prefix=${prefix} libdir=${prefix}/%{libdir} -includedir=${prefix}/include +includedir=${prefix}/include/botan-%{version_major}.%{version_minor} Name: Botan Description: Multi-platform C++ crypto library Version: %{version} -Libs: -L${libdir} -lbotan +Libs: -L${libdir} -lbotan-%{version_major}.%{version_minor} Libs.private: %{link_to} Cflags: -I${includedir} diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index 8e0de0183..b3e6f8197 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -17,10 +17,12 @@ #define BOTAN_VERSION_PATCH %{version_patch} #define BOTAN_VERSION_DATESTAMP %{version_datestamp} +#define BOTAN_VERSION_VC_REVISION "%{version_vc_rev}" + #define BOTAN_DISTRIBUTION_INFO "%{distribution_info}" #ifndef BOTAN_DLL - #define BOTAN_DLL %{dll_import_flags} + #define BOTAN_DLL %{visibility_attribute} #endif /* Chunk sizes */ diff --git a/src/build-data/cc/bcc.txt b/src/build-data/cc/bcc.txt index 93306dde1..f2ea46ef2 100644 --- a/src/build-data/cc/bcc.txt +++ b/src/build-data/cc/bcc.txt @@ -15,7 +15,6 @@ lang_flags "" warning_flags "" shared_flags "" -dll_import_flags "" ar_command lib diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt index 5f522cdb6..e5d52db3d 100644 --- a/src/build-data/cc/clang.txt +++ b/src/build-data/cc/clang.txt @@ -17,11 +17,12 @@ makefile_style unix lib_opt_flags "-O2" check_opt_flags "-O2" -shared_flags "-fPIC -fvisibility=hidden" +shared_flags "-fPIC" debug_flags -g no_debug_flags "-finline-functions" -dll_import_flags '__attribute__((visibility("default")))' +visibility_build_flags "-fvisibility=hidden" +visibility_attribute '__attribute__((visibility("default")))' <so_link_flags> # The default works for GNU ld and several other Unix linkers @@ -30,7 +31,8 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" <mach_opt> x86_64 -> "-march=SUBMODEL" -nehalem -> "-march=core2 -mssse3 -msse4.1" +nehalem -> "-march=corei7" +westmere -> "-march=corei7 -maes" </mach_opt> <mach_abi_linking> diff --git a/src/build-data/cc/ekopath.txt b/src/build-data/cc/ekopath.txt index 101f6babb..c6e8b6550 100644 --- a/src/build-data/cc/ekopath.txt +++ b/src/build-data/cc/ekopath.txt @@ -28,10 +28,9 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" athlon -> "-mcpu=athlon" pentium4 -> "-mcpu=pentium4" -opteron -> "-mcpu=opteron" -em64t -> "-mcpu=em64t" +k8 -> "-mcpu=opteron" core2 -> "-mcpu=core" -x86 -> "-mcpu=anyx86" +x86_32 -> "-mcpu=anyx86" x86_64 -> "-mcpu=athlon64" </mach_opt> diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index fde33cde2..3de85099c 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -13,15 +13,16 @@ add_lib_option -l lang_flags "-D_REENTRANT -Wno-long-long" warning_flags "-W -Wall" -maintainer_warning_flags "-Werror -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast" +maintainer_warning_flags "-Werror -Weffc++ -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast" lib_opt_flags "-O3" check_opt_flags "-O2" -shared_flags "-fPIC -fvisibility=hidden" +shared_flags "-fPIC" debug_flags -g no_debug_flags "-finline-functions" -dll_import_flags '__attribute__((visibility("default")))' +visibility_build_flags "-fvisibility=hidden" +visibility_attribute '__attribute__((visibility("default")))' makefile_style unix @@ -32,36 +33,54 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" # AIX doesn't seem to have soname support (weird...) aix -> "$(CXX) -shared -fPIC" +# OpenBSD doesn't use soname +openbsd -> "$(CXX) -shared -fPIC" + darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME)" solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME)" </so_link_flags> <mach_opt> -# Specializations first (they don't need to be, just clearer) -i386 -> "-mtune=i686 -momit-leaf-frame-pointer" -ppc601 -> "-mpowerpc -mcpu=601" - -# Until GCC gets -march support for these models -nehalem -> "-march=core2 -msse4.1 -msse4.2" -westmere -> "-march=core2 -maes -msse4.1 -msse4.2" -atom -> "-march=i686 -msse2 -mssse3" -cellppu -> "" -alpha-ev68 -> "-mcpu=ev6" -alpha-ev7 -> "-mcpu=ev6" - -# Default family options (SUBMODEL is substitued with the real submodel) -# Anything after the quotes is what should be *removed* from the submodel name -# before it's put into SUBMODEL. +# Avoid using -march=i[345]86, instead tune for generic +i386 -> "-mtune=generic -momit-leaf-frame-pointer" +i486 -> "-mtune=generic -momit-leaf-frame-pointer" +i586 -> "-mtune=generic -momit-leaf-frame-pointer" + +# Translate to GCC-speak +nehalem -> "-march=corei7 -momit-leaf-frame-pointer" +#westmere -> "-march=corei7 -maes -momit-leaf-frame-pointer" + +#nehalem -> "-march=core2 -msse4.1 -msse4.2 -momit-leaf-frame-pointer" +#westmere -> "-march=core2 -msse4.1 -msse4.2 -maes -momit-leaf-frame-pointer" + +sandybridge -> "-march=corei7-avx -momit-leaf-frame-pointer" +atom32 -> "-march=atom -momit-leaf-frame-pointer" + +ppc601 -> "-mpowerpc -mcpu=601" +cellppu -> "-mcpu=cell" +e500v2 -> "-mcpu=8548" + +# No scheduler in GCC for anything after EV67 +alpha-ev68 -> "-mcpu=ev67" +alpha-ev7 -> "-mcpu=ev67" + +# The patch from Debian bug 594159 has this, don't know why though... +sh4 -> "-m4 -mieee" + +# Default family options (SUBMODEL is substitued with the actual +# submodel name). Anything after the quotes is what should be +# *removed* from the submodel name before it's put into SUBMODEL. + alpha -> "-mcpu=SUBMODEL" alpha- arm -> "-march=SUBMODEL" -hitachi-sh -> "-mSUBMODEL" hitachi-sh +superh -> "-mSUBMODEL" sh hppa -> "-march=SUBMODEL" hppa ia64 -> "-mtune=SUBMODEL" m68k -> "-mSUBMODEL" mips32 -> "-mips1 -mcpu=SUBMODEL" mips32- mips64 -> "-mips3 -mcpu=SUBMODEL" mips64- -ppc -> "-mcpu=SUBMODEL" ppc +ppc32 -> "-mcpu=SUBMODEL" ppc ppc64 -> "-mcpu=SUBMODEL" ppc sparc32 -> "-mcpu=SUBMODEL -Wa,-xarch=v8plus" sparc32- sparc64 -> "-mcpu=v9 -mtune=SUBMODEL" diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt index a854a576d..034ea7444 100644 --- a/src/build-data/cc/msvc.txt +++ b/src/build-data/cc/msvc.txt @@ -14,8 +14,8 @@ check_opt_flags "/O2 /D_CONSOLE" lang_flags "/EHs /GR" warning_flags "/W3 /wd4275 /wd4267" -shared_flags "/DBOTAN_DLL=__declspec(dllexport)" -dll_import_flags "__declspec(dllimport)" +visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)" +visibility_attribute "__declspec(dllimport)" ar_command lib diff --git a/src/build-data/cc/sunstudio.txt b/src/build-data/cc/sunstudio.txt index 5fb4c6bb8..43e5fcf8a 100644 --- a/src/build-data/cc/sunstudio.txt +++ b/src/build-data/cc/sunstudio.txt @@ -40,13 +40,17 @@ nehalem -> "-xtarget=nehalem" sparc32-v9 -> "-xchip=ultra -xarch=v8" +ultrasparc3 -> "-xchip=ultra3" +niagra1 -> "-xchip=ultraT1" +niagra2 -> "-xchip=ultraT2" + sparc32 -> "-xchip=ultra -xarch=SUBMODEL" sparc32- -sparc64 -> "-xchip=SUBMODEL" sparc64- +sparc64 -> "-xchip=generic" </mach_opt> <mach_abi_linking> # Needed on some Linux distros -#linux -> "-library=stlport4" +linux -> "-library=stlport4" sparc64 -> "-xarch=v9" x86_64 -> "-m64" diff --git a/src/build-data/makefile/python.in b/src/build-data/makefile/python.in index 583c91eb5..74620fe06 100644 --- a/src/build-data/makefile/python.in +++ b/src/build-data/makefile/python.in @@ -3,6 +3,8 @@ CFLAGS = -Os LDFLAGS = WARN_FLAGS = %{warn_flags} +SERIES = %{version_major}.%{version_minor} + PYTHON_ROOT = /usr/lib/python%{python_version}/config PYTHON_INC = -I/usr/include/python%{python_version} PYTHON_SITE_PACKAGE_DIR = /usr/lib/python%{python_version}/site-packages/ @@ -19,7 +21,7 @@ all: $(BOTAN_PYTHON_MODDIR)/_botan.so $(BOTAN_PYTHON_MODDIR)/_botan.so: $(PYTHON_OBJS) cp %{python_dir}/*.py $(BOTAN_PYTHON_MODDIR) - $(CXX) -shared -Wl,-soname,$@ $(PYTHON_OBJS) -L. -L$(PYTHON_ROOT) $(LDFLAGS) -lbotan -lboost_python -o $@ + $(CXX) -shared -Wl,-soname,$@ $(PYTHON_OBJS) -L. -L$(PYTHON_ROOT) $(LDFLAGS) -lbotan-$(SERIES) -lboost_python -o $@ clean: rm -rf $(BOTAN_PYTHON_MODDIR)/* diff --git a/src/build-data/makefile/unix.in b/src/build-data/makefile/unix.in index 1a1128f81..5290beda8 100644 --- a/src/build-data/makefile/unix.in +++ b/src/build-data/makefile/unix.in @@ -9,13 +9,14 @@ LINK_TO = %{link_to} # Version Numbers VERSION = %{version} +SERIES = %{version_major}.%{version_minor} # Installation Settings DESTDIR = %{prefix} BINDIR = $(DESTDIR)/bin LIBDIR = $(DESTDIR)/%{libdir} -HEADERDIR = $(DESTDIR)/%{includedir}/botan +HEADERDIR = $(DESTDIR)/%{includedir}/botan-$(SERIES)/botan DOCDIR = $(DESTDIR)/%{docdir}/botan-$(VERSION) PKGCONF_DIR = $(LIBDIR)/pkgconfig @@ -52,7 +53,7 @@ CHECK_FLAGS = $(CHECK_OPT) $(LANG_FLAGS) $(WARN_FLAGS) LIBRARIES = $(STATIC_LIB) LIBNAME = %{lib_prefix}libbotan -STATIC_LIB = $(LIBNAME).a +STATIC_LIB = $(LIBNAME)-$(SERIES).a all: $(LIBRARIES) @@ -85,6 +86,7 @@ clean: distclean: clean $(RM_R) %{build_dir} $(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG) + $(RM) botan_all.cpp botan_all.h install: $(LIBRARIES) docs $(ECHO) "Installing Botan into $(DESTDIR)... " diff --git a/src/build-data/makefile/unix_shr.in b/src/build-data/makefile/unix_shr.in index c311d9924..31060afbb 100644 --- a/src/build-data/makefile/unix_shr.in +++ b/src/build-data/makefile/unix_shr.in @@ -11,13 +11,14 @@ LINK_TO = %{link_to} # Version Numbers VERSION = %{version} +SERIES = %{version_major}.%{version_minor} # Installation Settings DESTDIR = %{prefix} BINDIR = $(DESTDIR)/bin LIBDIR = $(DESTDIR)/%{libdir} -HEADERDIR = $(DESTDIR)/%{includedir}/botan +HEADERDIR = $(DESTDIR)/%{includedir}/botan-$(SERIES)/botan DOCDIR = $(DESTDIR)/%{docdir}/botan-$(VERSION) PKGCONF_DIR = $(LIBDIR)/pkgconfig @@ -54,12 +55,12 @@ CHECK_FLAGS = $(CHECK_OPT) $(LANG_FLAGS) $(WARN_FLAGS) LIBRARIES = $(STATIC_LIB) $(SHARED_LIB) LIBNAME = %{lib_prefix}libbotan -STATIC_LIB = $(LIBNAME).a +STATIC_LIB = $(LIBNAME)-$(SERIES).a -SONAME = $(LIBNAME)-%{version_major}.%{version_minor}.%{so_suffix} +SONAME = $(LIBNAME)-$(SERIES).%{so_suffix}.%{so_abi_rev} SHARED_LIB = $(SONAME).%{version_patch} -SYMLINK = libbotan.%{so_suffix} +SYMLINK = $(LIBNAME)-$(SERIES).%{so_suffix} all: $(LIBRARIES) @@ -99,6 +100,7 @@ clean: distclean: clean $(RM_R) %{build_dir} $(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG) + $(RM) botan_all.cpp botan_all.h install: $(LIBRARIES) docs $(ECHO) "Installing Botan into $(DESTDIR)... " diff --git a/src/build-data/os/mingw.txt b/src/build-data/os/mingw.txt index 08f85b4db..1268298cb 100644 --- a/src/build-data/os/mingw.txt +++ b/src/build-data/os/mingw.txt @@ -14,15 +14,13 @@ header_dir include lib_dir lib doc_dir share/doc -install_cmd_data "install -m 644" -install_cmd_exec "install -m 755" - <aliases> msys mingw32 </aliases> <target_features> +loadlibrary win32_virtual_lock win32_get_systemtime </target_features> diff --git a/src/build-data/os/nacl.txt b/src/build-data/os/nacl.txt new file mode 100644 index 000000000..3df798ed8 --- /dev/null +++ b/src/build-data/os/nacl.txt @@ -0,0 +1,4 @@ + +<target_features> +gettimeofday +</target_features> diff --git a/src/build-data/os/solaris.txt b/src/build-data/os/solaris.txt index 47e7bccbc..0ed785036 100644 --- a/src/build-data/os/solaris.txt +++ b/src/build-data/os/solaris.txt @@ -1,5 +1,8 @@ os_type unix +install_cmd_data '/usr/ucb/install -m 644' +install_cmd_exec '/usr/ucb/install -m 755' + <target_features> posix_mlock gettimeofday diff --git a/src/build-data/scripts/dist.py b/src/build-data/scripts/dist.py new file mode 100755 index 000000000..8a69e7aa6 --- /dev/null +++ b/src/build-data/scripts/dist.py @@ -0,0 +1,168 @@ +#!/usr/bin/python + +import optparse +import subprocess +import logging +import os +import sys +import shutil +import tarfile +import errno + +def check_subprocess_results(subproc, name): + (stdout, stderr) = subproc.communicate() + + stdout = stdout.strip() + stderr = stderr.strip() + + if subproc.returncode != 0: + if stdout != '': + logging.error(stdout) + if stderr != '': + logging.error(stderr) + raise Exception('Running %s failed' % (name)) + else: + if stderr != '': + logging.debug(stderr) + + return stdout + +def run_monotone(db, args): + mtn = subprocess.Popen(['mtn', '--db', db] + args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + return check_subprocess_results(mtn, 'mtn') + +def gpg_sign(file, keyid): + print file + gpg = subprocess.Popen(['gpg', '--armor', '--detach-sign', + '--local-user', keyid, file], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + check_subprocess_results(gpg, 'gpg') + +def parse_args(args): + parser = optparse.OptionParser() + parser.add_option('--verbose', action='store_true', + default=False, help='Extra debug output') + + parser.add_option('--output-dir', metavar='DIR', + default='.', + help='Where to place output (default %default)') + + parser.add_option('--mtn-db', metavar='DB', + default=os.getenv('BOTAN_MTN_DB', ''), + help='Set monotone db (default \'%default\')') + + parser.add_option('--pgp-key-id', metavar='KEYID', + default='EFBADFBC', + help='PGP signing key (default %default)') + + return parser.parse_args(args) + +def remove_file_if_exists(fspath): + try: + os.unlink(fspath) + except OSError, e: + if e.errno != errno.ENOENT: + raise + +def main(args = None): + if args is None: + args = sys.argv[1:] + + (options, args) = parse_args(args) + + def log_level(): + if options.verbose: + return logging.DEBUG + return logging.INFO + + logging.basicConfig(stream = sys.stdout, + format = '%(levelname) 7s: %(message)s', + level = log_level()) + + if options.mtn_db == '': + logging.error('No monotone db set (use --mtn-db)') + return 1 + + if not os.access(options.mtn_db, os.R_OK): + logging.error('Monotone db %s not found' % (options.mtn_db)) + return 1 + + if len(args) != 1: + logging.error('Usage: %s version' % (sys.argv[0])) + return 1 + + try: + version = args[0] + + rev_id = run_monotone(options.mtn_db, + ['automate', 'select', 't:' + version]) + + if rev_id == '': + logging.error('No revision for %s found' % (version)) + return 2 + + output_basename = 'Botan-' + version + output_name = os.path.join(options.output_dir, output_basename) + + output_tgz = output_name + '.tgz' + output_tbz = output_name + '.tbz' + + logging.info('Found revision id %s' % (rev_id)) + + if os.access(output_name, os.X_OK): + shutil.rmtree(output_name) + + run_monotone(options.mtn_db, + ['checkout', '-r', rev_id, output_name]) + + shutil.rmtree(os.path.join(output_name, '_MTN')) + remove_file_if_exists(os.path.join(output_name, '.mtn-ignore')) + + version_file = os.path.join(output_name, 'botan_version.py') + if os.access(version_file, os.R_OK): + # rewrite botan_version.py + + contents = open(version_file).readlines() + + def content_rewriter(): + for line in contents: + if line == 'release_vc_rev = None\n': + yield 'release_vc_rev = \'mtn:%s\'\n' % (rev_id) + else: + yield line + + open(version_file, 'w').write(''.join(list(content_rewriter()))) + + os.chdir(options.output_dir) + + remove_file_if_exists(output_tgz) + remove_file_if_exists(output_tgz + '.asc') + archive = tarfile.open(output_tgz, 'w:gz') + archive.add(output_basename) + archive.close() + if options.pgp_key_id != '': + gpg_sign(output_tgz, options.pgp_key_id) + + remove_file_if_exists(output_tbz) + remove_file_if_exists(output_tbz + '.asc') + archive = tarfile.open(output_tbz, 'w:bz2') + archive.add(output_basename) + archive.close() + if options.pgp_key_id != '': + gpg_sign(output_tbz, options.pgp_key_id) + + shutil.rmtree(output_name) + + except Exception, e: + import traceback + traceback.print_exc(file=sys.stderr) + logging.error(str(e)) + return 1 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt index c42d909b5..33a872053 100644 --- a/src/cert/cvc/info.txt +++ b/src/cert/cvc/info.txt @@ -1,6 +1,6 @@ define CARD_VERIFIABLE_CERTIFICATES -load_on auto +load_on request <header:public> cvc_ado.h diff --git a/src/cert/x509cert/x509_ext.cpp b/src/cert/x509cert/x509_ext.cpp index 462b29669..6e0befaf3 100644 --- a/src/cert/x509cert/x509_ext.cpp +++ b/src/cert/x509cert/x509_ext.cpp @@ -443,6 +443,9 @@ class Policy_Information : public ASN1_Object public: OID oid; + Policy_Information() {} + Policy_Information(const OID& oid) : oid(oid) {} + void encode_into(DER_Encoder& codec) const { codec.start_cons(SEQUENCE) @@ -466,18 +469,16 @@ class Policy_Information : public ASN1_Object */ MemoryVector<byte> Certificate_Policies::encode_inner() const { - // FIXME -#if 1 - throw Internal_Error("Certificate_Policies::encode_inner: Bugged"); -#else std::vector<Policy_Information> policies; + for(size_t i = 0; i != oids.size(); ++i) + policies.push_back(oids[i]); + return DER_Encoder() .start_cons(SEQUENCE) .encode_list(policies) .end_cons() .get_contents(); -#endif } /* @@ -491,6 +492,10 @@ void Certificate_Policies::decode_inner(const MemoryRegion<byte>& in) .start_cons(SEQUENCE) .decode_list(policies) .end_cons(); + + oids.clear(); + for(size_t i = 0; i != policies.size(); ++i) + oids.push_back(policies[i].oid); } /* diff --git a/src/codec/base64/base64.cpp b/src/codec/base64/base64.cpp index d6c5ec7c0..6a53a7a9a 100644 --- a/src/codec/base64/base64.cpp +++ b/src/codec/base64/base64.cpp @@ -97,5 +97,155 @@ std::string base64_encode(const MemoryRegion<byte>& input) return base64_encode(&input[0], input.size()); } +size_t base64_decode(byte output[], + const char input[], + size_t input_length, + size_t& input_consumed, + bool final_inputs, + bool ignore_ws) + { + /* + * Base64 Decoder Lookup Table + * Warning: assumes ASCII encodings + */ + static const byte BASE64_TO_BIN[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, + 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, + 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + byte* out_ptr = output; + byte decode_buf[4]; + size_t decode_buf_pos = 0; + size_t final_truncate = 0; + + clear_mem(output, input_length * 3 / 4); + + for(size_t i = 0; i != input_length; ++i) + { + const byte bin = BASE64_TO_BIN[static_cast<byte>(input[i])]; + + if(bin <= 0x3F) + { + decode_buf[decode_buf_pos] = bin; + decode_buf_pos += 1; + } + else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws))) + { + std::string bad_char(1, input[i]); + if(bad_char == "\t") + bad_char = "\\t"; + else if(bad_char == "\n") + bad_char = "\\n"; + else if(bad_char == "\r") + bad_char = "\\r"; + + throw std::invalid_argument( + std::string("base64_decode: invalid base64 character '") + + bad_char + "'"); + } + + /* + * If we're at the end of the input, pad with 0s and truncate + */ + if(final_inputs && (i == input_length - 1)) + { + if(decode_buf_pos) + { + for(size_t i = decode_buf_pos; i != 4; ++i) + decode_buf[i] = 0; + final_truncate = (4 - decode_buf_pos); + decode_buf_pos = 4; + } + } + + if(decode_buf_pos == 4) + { + out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4); + out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2); + out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3]; + + out_ptr += 3; + decode_buf_pos = 0; + input_consumed = i+1; + } + } + + while(input_consumed < input_length && + BASE64_TO_BIN[static_cast<byte>(input[input_consumed])] == 0x80) + { + ++input_consumed; + } + + size_t written = (out_ptr - output) - final_truncate; + + return written; + } + +size_t base64_decode(byte output[], + const char input[], + size_t input_length, + bool ignore_ws) + { + size_t consumed = 0; + size_t written = base64_decode(output, input, input_length, + consumed, true, ignore_ws); + + if(consumed != input_length) + throw std::invalid_argument("base64_decode: input did not have full bytes"); + + return written; + } + +size_t base64_decode(byte output[], + const std::string& input, + bool ignore_ws) + { + return base64_decode(output, &input[0], input.length(), ignore_ws); + } + +SecureVector<byte> base64_decode(const char input[], + size_t input_length, + bool ignore_ws) + { + SecureVector<byte> bin((round_up<size_t>(input_length, 4) * 3) / 4); + + size_t written = base64_decode(&bin[0], + input, + input_length, + ignore_ws); + + bin.resize(written); + return bin; + } + +SecureVector<byte> base64_decode(const std::string& input, + bool ignore_ws) + { + return base64_decode(&input[0], input.size(), ignore_ws); + } + } diff --git a/src/codec/base64/base64.h b/src/codec/base64/base64.h index 6daac73d8..23a2558bd 100644 --- a/src/codec/base64/base64.h +++ b/src/codec/base64/base64.h @@ -48,6 +48,76 @@ std::string BOTAN_DLL base64_encode(const byte input[], */ std::string BOTAN_DLL base64_encode(const MemoryRegion<byte>& input); +/** +* Perform base64 decoding +* @param output an array of at least input_length*3/4 bytes +* @param input some base64 input +* @param input_length length of input in bytes +* @param input_consumed is an output parameter which says how many +* bytes of input were actually consumed. If less than +* input_length, then the range input[consumed:length] +* should be passed in later along with more input. +* @param final_inputs true iff this is the last input, in which case + padding is allowed +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_DLL base64_decode(byte output[], + const char input[], + size_t input_length, + size_t& input_consumed, + bool final_inputs, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param output an array of at least input_length*3/4 bytes +* @param input some base64 input +* @param input_length length of input in bytes +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_DLL base64_decode(byte output[], + const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param output an array of at least input_length/3*4 bytes +* @param input some base64 input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_DLL base64_decode(byte output[], + const std::string& input, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param input some base64 input +* @param input_length the length of input in bytes +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded base64 output +*/ +SecureVector<byte> BOTAN_DLL base64_decode(const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param input some base64 input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded base64 output +*/ +SecureVector<byte> BOTAN_DLL base64_decode(const std::string& input, + bool ignore_ws = true); + } #endif diff --git a/src/codec/hex/hex.cpp b/src/codec/hex/hex.cpp index 49d6e7190..41ba1298d 100644 --- a/src/codec/hex/hex.cpp +++ b/src/codec/hex/hex.cpp @@ -37,9 +37,7 @@ void hex_encode(char output[], std::string hex_encode(const MemoryRegion<byte>& input, bool uppercase) { - return hex_encode(&input[0], - input.size(), - uppercase); + return hex_encode(&input[0], input.size(), uppercase); } std::string hex_encode(const byte input[], @@ -47,7 +45,10 @@ std::string hex_encode(const byte input[], bool uppercase) { std::string output(2 * input_length, 0); - hex_encode(&output[0], input, input_length, uppercase); + + if(input_length) + hex_encode(&output[0], input, input_length, uppercase); + return output; } diff --git a/src/constructs/srp6/info.txt b/src/constructs/srp6/info.txt new file mode 100644 index 000000000..7962bd383 --- /dev/null +++ b/src/constructs/srp6/info.txt @@ -0,0 +1,7 @@ +define SRP6 + +<requires> +bigint +hash +dl_group +</requires> diff --git a/src/constructs/srp6/srp6.cpp b/src/constructs/srp6/srp6.cpp new file mode 100644 index 000000000..287f0bdfb --- /dev/null +++ b/src/constructs/srp6/srp6.cpp @@ -0,0 +1,156 @@ +/* +* SRP-6a +* (C) 2011 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/srp6.h> +#include <botan/dl_group.h> +#include <botan/libstate.h> +#include <botan/numthry.h> +#include <memory> + +namespace Botan { + +namespace { + +BigInt hash_seq(const std::string& hash_id, + size_t pad_to, + const BigInt& in1, + const BigInt& in2) + { + std::auto_ptr<HashFunction> hash_fn( + global_state().algorithm_factory().make_hash_function(hash_id)); + + hash_fn->update(BigInt::encode_1363(in1, pad_to)); + hash_fn->update(BigInt::encode_1363(in2, pad_to)); + + return BigInt::decode(hash_fn->final()); + } + +BigInt hash_seq(const std::string& hash_id, + size_t pad_to, + const BigInt& in1, + const BigInt& in2, + const BigInt& in3) + { + std::auto_ptr<HashFunction> hash_fn( + global_state().algorithm_factory().make_hash_function(hash_id)); + + hash_fn->update(BigInt::encode_1363(in1, pad_to)); + hash_fn->update(BigInt::encode_1363(in2, pad_to)); + hash_fn->update(BigInt::encode_1363(in3, pad_to)); + + return BigInt::decode(hash_fn->final()); + } + +BigInt compute_x(const std::string& hash_id, + const std::string& identifier, + const std::string& password, + const MemoryRegion<byte>& salt) + { + std::auto_ptr<HashFunction> hash_fn( + global_state().algorithm_factory().make_hash_function(hash_id)); + + hash_fn->update(identifier); + hash_fn->update(":"); + hash_fn->update(password); + + SecureVector<byte> inner_h = hash_fn->final(); + + hash_fn->update(salt); + hash_fn->update(inner_h); + + SecureVector<byte> outer_h = hash_fn->final(); + + return BigInt::decode(outer_h); + } + +} + +std::pair<BigInt, SymmetricKey> +SRP6_Client_Session:: step1(const std::string& identifier, + const std::string& password, + const std::string& group_id, + const std::string& hash_id, + const MemoryRegion<byte>& salt, + const BigInt& B, + RandomNumberGenerator& rng) + { + DL_Group group(group_id); + const BigInt& g = group.get_g(); + const BigInt& p = group.get_p(); + + const size_t p_bytes = group.get_p().bytes(); + + if(B % p == 0) + throw std::runtime_error("Invalid SRP parameter from server"); + + BigInt k = hash_seq(hash_id, p_bytes, p, g); + + BigInt a(rng, p.bits() - 1); + + BigInt A = power_mod(g, a, p); + + BigInt u = hash_seq(hash_id, p_bytes, A, B); + + const BigInt x = compute_x(hash_id, identifier, password, salt); + + BigInt S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p); + + SymmetricKey Sk(BigInt::encode_1363(S, p_bytes)); + + return std::make_pair(A, Sk); + } + +BigInt SRP6_Client_Session::generate_verifier(const std::string& identifier, + const std::string& password, + const MemoryRegion<byte>& salt, + const std::string& group_id, + const std::string& hash_id) + { + const BigInt x = compute_x(hash_id, identifier, password, salt); + + DL_Group group(group_id); + return power_mod(group.get_g(), x, group.get_p()); + } + +BigInt SRP6_Server_Session::step1(const BigInt& v, + const std::string& group_id, + const std::string& hash_id, + RandomNumberGenerator& rng) + { + DL_Group group(group_id); + const BigInt& g = group.get_g(); + const BigInt& p = group.get_p(); + + p_bytes = p.bytes(); + + BigInt k = hash_seq(hash_id, p_bytes, p, g); + + BigInt b(rng, p.bits() - 1); + + B = (v*k + power_mod(g, b, p)) % p; + + this->v = v; + this->b = b; + this->p = p; + this->hash_id = hash_id; + + return B; + } + +SymmetricKey SRP6_Server_Session::step2(const BigInt& A) + { + if(A % p == 0) + throw std::runtime_error("Invalid SRP parameter from client"); + + BigInt u = hash_seq(hash_id, p_bytes, A, B); + + BigInt S = power_mod(A * power_mod(v, u, p), b, p); + + return BigInt::encode_1363(S, p_bytes); + } + +} diff --git a/src/constructs/srp6/srp6.h b/src/constructs/srp6/srp6.h new file mode 100644 index 000000000..01bd2a4c7 --- /dev/null +++ b/src/constructs/srp6/srp6.h @@ -0,0 +1,84 @@ +/* +* SRP-6a (RFC 5054 compatatible) +* (C) 2011 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_RFC5054_SRP6_H__ +#define BOTAN_RFC5054_SRP6_H__ + +#include <botan/bigint.h> +#include <botan/hash.h> +#include <botan/rng.h> +#include <botan/symkey.h> +#include <string> + +namespace Botan { + +/** +* Represents a SRP-6a client session +*/ +class BOTAN_DLL SRP6_Client_Session + { + public: + + /** + * Client side step 1 + * @param username the username we are attempting login for + * @param password the password we are attempting to use + * @param group_id specifies the shared SRP group + * @param hash_id specifies a secure hash function + * @param salt is the salt value sent by the server + * @param B is the server's public value + * @param rng is a random number generator + * + * @return (A,K) the client public key and the shared secret key + */ + std::pair<BigInt,SymmetricKey> step1(const std::string& username, + const std::string& password, + const std::string& group_id, + const std::string& hash_id, + const MemoryRegion<byte>& salt, + const BigInt& B, + RandomNumberGenerator& rng); + + /** + * Generate a new SRP-6 verifier + * @param identifier a username or other client identifier + * @param password the secret used to authenticate user + * @param salt a randomly chosen value, at least 128 bits long + */ + static BigInt generate_verifier(const std::string& identifier, + const std::string& password, + const MemoryRegion<byte>& salt, + const std::string& group_id, + const std::string& hash_id); + }; + +/** +* Represents a SRP-6a server session +*/ +class BOTAN_DLL SRP6_Server_Session + { + public: + /** + * Server side step 1 + * @param v the verification value saved from client registration + */ + BigInt step1(const BigInt& v, + const std::string& group_id, + const std::string& hash_id, + RandomNumberGenerator& rng); + + SymmetricKey step2(const BigInt& A); + + private: + std::string hash_id; + BigInt B, b, v, S, p; + size_t p_bytes; + }; + +} + +#endif diff --git a/src/constructs/srp6/srp6_files.cpp b/src/constructs/srp6/srp6_files.cpp new file mode 100644 index 000000000..2d685614f --- /dev/null +++ b/src/constructs/srp6/srp6_files.cpp @@ -0,0 +1,69 @@ +/* +* SRP-6a File Handling +* (C) 2011 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/srp6_files.h> +#include <botan/parsing.h> +#include <botan/base64.h> +#include <fstream> + +namespace Botan { + +SRP6_Authenticator_File::SRP6_Authenticator_File(const std::string& filename) + { + std::ifstream in(filename.c_str()); + + if(!in) + return; // no entries + + while(in.good()) + { + std::string line; + std::getline(in, line); + + std::vector<std::string> parts = split_on(line, ':'); + + if(parts.size() != 4) + throw Decoding_Error("Invalid line in SRP authenticator file"); + + std::string username = parts[0]; + BigInt v = BigInt::decode(base64_decode(parts[1])); + MemoryVector<byte> salt = base64_decode(parts[2]); + BigInt group_id_idx = BigInt::decode(base64_decode(parts[3])); + + std::string group_id; + + if(group_id_idx == 1) + group_id = "modp/srp/1024"; + else if(group_id_idx == 2) + group_id = "modp/srp/1536"; + else if(group_id_idx == 3) + group_id = "modp/srp/2048"; + else + continue; // unknown group, ignored + + entries[username] = SRP6_Data(v, salt, group_id); + } + } + +bool SRP6_Authenticator_File::lookup_user(const std::string& username, + BigInt& v, + MemoryVector<byte>& salt, + std::string& group_id) const + { + std::map<std::string, SRP6_Data>::const_iterator i = entries.find(username); + + if(i == entries.end()) + return false; + + v = i->second.v; + salt = i->second.salt; + group_id = i->second.group_id; + + return true; + } + +} diff --git a/src/constructs/srp6/srp6_files.h b/src/constructs/srp6/srp6_files.h new file mode 100644 index 000000000..1def0fd51 --- /dev/null +++ b/src/constructs/srp6/srp6_files.h @@ -0,0 +1,53 @@ +/* +* SRP-6a File Handling +* (C) 2011 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SRP6A_FILES_H__ +#define BOTAN_SRP6A_FILES_H__ + +#include <botan/bigint.h> +#include <string> +#include <map> + +namespace Botan { + +/** +* A GnuTLS compatible SRP6 authenticator file +*/ +class SRP6_Authenticator_File + { + public: + /** + * @param filename will be opened and processed as a SRP + * authenticator file + */ + SRP6_Authenticator_File(const std::string& filename); + + bool lookup_user(const std::string& username, + BigInt& v, + MemoryVector<byte>& salt, + std::string& group_id) const; + private: + struct SRP6_Data + { + SRP6_Data() {} + + SRP6_Data(const BigInt& v, + const MemoryRegion<byte>& salt, + const std::string& group_id) : + v(v), salt(salt), group_id(group_id) {} + + BigInt v; + MemoryVector<byte> salt; + std::string group_id; + }; + + std::map<std::string, SRP6_Data> entries; + }; + +} + +#endif diff --git a/src/engine/aes_isa_eng/aes_isa_engine.cpp b/src/engine/aes_isa_eng/aes_isa_engine.cpp index 7f541d583..e56f6e9ca 100644 --- a/src/engine/aes_isa_eng/aes_isa_engine.cpp +++ b/src/engine/aes_isa_eng/aes_isa_engine.cpp @@ -8,8 +8,8 @@ #include <botan/internal/aes_isa_engine.h> #include <botan/cpuid.h> -#if defined(BOTAN_HAS_AES_INTEL) - #include <botan/aes_intel.h> +#if defined(BOTAN_HAS_AES_NI) + #include <botan/aes_ni.h> #endif namespace Botan { @@ -18,15 +18,15 @@ BlockCipher* AES_ISA_Engine::find_block_cipher(const SCAN_Name& request, Algorithm_Factory&) const { -#if defined(BOTAN_HAS_AES_INTEL) +#if defined(BOTAN_HAS_AES_NI) if(CPUID::has_aes_ni()) { if(request.algo_name() == "AES-128") - return new AES_128_Intel; + return new AES_128_NI; if(request.algo_name() == "AES-192") - return new AES_192_Intel; + return new AES_192_NI; if(request.algo_name() == "AES-256") - return new AES_256_Intel; + return new AES_256_NI; } #endif diff --git a/src/engine/core_engine/core_modes.cpp b/src/engine/core_engine/core_modes.cpp index 035cd41c7..8a929e880 100644 --- a/src/engine/core_engine/core_modes.cpp +++ b/src/engine/core_engine/core_modes.cpp @@ -1,6 +1,6 @@ /* * Core Engine -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -179,8 +179,8 @@ Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher, * Get a cipher object */ Keyed_Filter* Core_Engine::get_cipher(const std::string& algo_spec, - Cipher_Dir direction, - Algorithm_Factory& af) + Cipher_Dir direction, + Algorithm_Factory& af) { std::vector<std::string> algo_parts = split_on(algo_spec, '/'); if(algo_parts.empty()) @@ -197,8 +197,12 @@ Keyed_Filter* Core_Engine::get_cipher(const std::string& algo_spec, if(!block_cipher) return 0; - if(algo_parts.size() != 2 && algo_parts.size() != 3) - return 0; + if(algo_parts.size() >= 4) + return 0; // 4 part mode, not something we know about + + if(algo_parts.size() < 2) + throw Lookup_Error("Cipher specification '" + algo_spec + + "' is missing mode identifier"); std::string mode = algo_parts[1]; diff --git a/src/engine/core_engine/lookup_block.cpp b/src/engine/core_engine/lookup_block.cpp index cc5239dd1..c27a13237 100644 --- a/src/engine/core_engine/lookup_block.cpp +++ b/src/engine/core_engine/lookup_block.cpp @@ -17,6 +17,10 @@ #include <botan/blowfish.h> #endif +#if defined(BOTAN_HAS_CAMELLIA) + #include <botan/camellia.h> +#endif + #if defined(BOTAN_HAS_CAST) #include <botan/cast128.h> #include <botan/cast256.h> @@ -130,6 +134,11 @@ BlockCipher* Core_Engine::find_block_cipher(const SCAN_Name& request, return new Blowfish; #endif +#if defined(BOTAN_HAS_CAMELLIA) + if(request.algo_name() == "Camellia") + return new Camellia; +#endif + #if defined(BOTAN_HAS_CAST) if(request.algo_name() == "CAST-128") return new CAST_128; diff --git a/src/engine/simd_engine/info.txt b/src/engine/simd_engine/info.txt index aaf218561..229b1daaf 100644 --- a/src/engine/simd_engine/info.txt +++ b/src/engine/simd_engine/info.txt @@ -11,5 +11,5 @@ simd_engine.h </header:internal> <requires> -simd_32 +simd </requires> diff --git a/src/entropy/dev_random/dev_random.cpp b/src/entropy/dev_random/dev_random.cpp index b15240aba..d14ae43ae 100644 --- a/src/entropy/dev_random/dev_random.cpp +++ b/src/entropy/dev_random/dev_random.cpp @@ -12,6 +12,7 @@ #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> +#include <string.h> namespace Botan { diff --git a/src/entropy/egd/es_egd.cpp b/src/entropy/egd/es_egd.cpp index d2ce2706b..b2b629930 100644 --- a/src/entropy/egd/es_egd.cpp +++ b/src/entropy/egd/es_egd.cpp @@ -89,7 +89,7 @@ size_t EGD_EntropySource::EGD_Socket::read(byte outbuf[], size_t length) throw std::runtime_error("Reading response length from EGD failed"); if(out_len > egd_read_command[1]) - throw std::runtime_error("Bogus length field recieved from EGD"); + throw std::runtime_error("Bogus length field received from EGD"); ssize_t count = ::read(m_fd, outbuf, out_len); diff --git a/src/entropy/hres_timer/hres_timer.cpp b/src/entropy/hres_timer/hres_timer.cpp index 7313590e5..dd1fc6f7c 100644 --- a/src/entropy/hres_timer/hres_timer.cpp +++ b/src/entropy/hres_timer/hres_timer.cpp @@ -1,6 +1,6 @@ /* * High Resolution Timestamp Entropy Source -* (C) 1999-2009 Jack Lloyd +* (C) 1999-2009,2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -22,9 +22,44 @@ void High_Resolution_Timestamp::poll(Entropy_Accumulator& accum) { // If Windows, grab the Performance Counter (usually TSC or PIT) #if defined(BOTAN_TARGET_OS_IS_WINDOWS) + { LARGE_INTEGER tv; ::QueryPerformanceCounter(&tv); accum.add(tv.QuadPart, 0); + } +#endif + +#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) + +#define CLOCK_POLL(src) \ + do { \ + struct timespec ts; \ + clock_gettime(src, &ts); \ + accum.add(&ts, sizeof(ts), 0); \ + } while(0) + +#if defined(CLOCK_REALTIME) + CLOCK_POLL(CLOCK_REALTIME); +#endif + +#if defined(CLOCK_MONOTONIC) + CLOCK_POLL(CLOCK_MONOTONIC); +#endif + +#if defined(CLOCK_MONOTONIC_RAW) + CLOCK_POLL(CLOCK_MONOTONIC_RAW); +#endif + +#if defined(CLOCK_PROCESS_CPUTIME_ID) + CLOCK_POLL(CLOCK_PROCESS_CPUTIME_ID); +#endif + +#if defined(CLOCK_THREAD_CPUTIME_ID) + CLOCK_POLL(CLOCK_THREAD_CPUTIME_ID); +#endif + +#undef CLOCK_POLL + #endif #if BOTAN_USE_GCC_INLINE_ASM diff --git a/src/entropy/hres_timer/hres_timer.h b/src/entropy/hres_timer/hres_timer.h index c693b8d4e..8b95c8308 100644 --- a/src/entropy/hres_timer/hres_timer.h +++ b/src/entropy/hres_timer/hres_timer.h @@ -14,6 +14,9 @@ namespace Botan { /** * Entropy source using high resolution timers +* +* @note Any results from timers are marked as not contributing entropy +* to the poll, as a local attacker could observe them directly. */ class High_Resolution_Timestamp : public EntropySource { diff --git a/src/entropy/unix_procs/unix_cmd.cpp b/src/entropy/unix_procs/unix_cmd.cpp index f4ae5054c..930444075 100644 --- a/src/entropy/unix_procs/unix_cmd.cpp +++ b/src/entropy/unix_procs/unix_cmd.cpp @@ -12,6 +12,7 @@ #include <sys/time.h> #include <sys/types.h> #include <sys/wait.h> +#include <string.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> diff --git a/src/filters/buf_filt.cpp b/src/filters/buf_filt.cpp index b332d74b8..ca3fa9a3c 100644 --- a/src/filters/buf_filt.cpp +++ b/src/filters/buf_filt.cpp @@ -82,7 +82,7 @@ void Buffered_Filter::write(const byte input[], size_t input_size) void Buffered_Filter::end_msg() { if(buffer_pos < final_minimum) - throw std::runtime_error("Buffered_Operation::final - not enough input"); + throw std::runtime_error("Buffered filter end_msg without enough input"); size_t spare_blocks = (buffer_pos - final_minimum) / main_block_mod; diff --git a/src/filters/codec_filt/b64_filt.cpp b/src/filters/codec_filt/b64_filt.cpp index 8a90f8b5f..9341571d4 100644 --- a/src/filters/codec_filt/b64_filt.cpp +++ b/src/filters/codec_filt/b64_filt.cpp @@ -14,32 +14,6 @@ namespace Botan { /* -* Base64 Decoder Lookup Table -* Warning: assumes ASCII encodings -*/ -static const byte BASE64_TO_BIN[256] = { -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F, 0x34, 0x35, 0x36, 0x37, -0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, -0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, -0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, -0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; - -/* * Base64_Encoder Constructor */ Base64_Encoder::Base64_Encoder(bool breaks, size_t length, bool t_n) : @@ -68,6 +42,7 @@ void Base64_Encoder::encode_and_send(const byte input[], size_t length, do_output(&out[0], produced); + // FIXME: s/proc/consumed/? input += proc; length -= proc; } @@ -138,58 +113,9 @@ void Base64_Encoder::end_msg() /* * Base64_Decoder Constructor */ -Base64_Decoder::Base64_Decoder(Decoder_Checking c) : checking(c) - { - in.resize(48); - out.resize(3); - position = 0; - } - -/* -* Check if a character is a valid Base64 char -*/ -bool Base64_Decoder::is_valid(byte in) - { - return (BASE64_TO_BIN[in] != 0x80); - } - -/* -* Base64 Decoding Operation -*/ -void Base64_Decoder::decode(const byte in[4], byte out[3]) - { - out[0] = ((BASE64_TO_BIN[in[0]] << 2) | (BASE64_TO_BIN[in[1]] >> 4)); - out[1] = ((BASE64_TO_BIN[in[1]] << 4) | (BASE64_TO_BIN[in[2]] >> 2)); - out[2] = ((BASE64_TO_BIN[in[2]] << 6) | (BASE64_TO_BIN[in[3]])); - } - -/* -* Decode and send a block -*/ -void Base64_Decoder::decode_and_send(const byte block[], size_t length) - { - for(size_t i = 0; i != length; i += 4) - { - decode(block + i, &out[0]); - send(out, 3); - } - } - -/* -* Handle processing an invalid character -*/ -void Base64_Decoder::handle_bad_char(byte c) +Base64_Decoder::Base64_Decoder(Decoder_Checking c) : + checking(c), in(64), out(48), position(0) { - if(c == '=' || checking == NONE) - return; - - if((checking == IGNORE_WS) && Charset::is_space(c)) - return; - - throw Decoding_Error( - std::string("Base64_Decoder: Invalid base64 character '") + - static_cast<char>(c) + "'" - ); } /* @@ -197,18 +123,32 @@ void Base64_Decoder::handle_bad_char(byte c) */ void Base64_Decoder::write(const byte input[], size_t length) { - for(size_t i = 0; i != length; ++i) + while(length) { - if(is_valid(input[i])) - in[position++] = input[i]; - else - handle_bad_char(input[i]); + size_t to_copy = std::min<size_t>(length, in.size() - position); + copy_mem(&in[position], input, to_copy); + position += to_copy; + + size_t consumed = 0; + size_t written = base64_decode(&out[0], + reinterpret_cast<const char*>(&in[0]), + position, + consumed, + false, + checking != FULL_CHECK); + + send(out, written); - if(position == in.size()) + if(consumed != position) { - decode_and_send(&in[0], in.size()); - position = 0; + copy_mem(&in[0], &in[consumed], position - consumed); + position = position - consumed; } + else + position = 0; + + length -= to_copy; + input += to_copy; } } @@ -217,21 +157,22 @@ void Base64_Decoder::write(const byte input[], size_t length) */ void Base64_Decoder::end_msg() { - if(position != 0) - { - size_t start_of_last_block = 4 * (position / 4), - left_over = position % 4; - decode_and_send(&in[0], start_of_last_block); + size_t consumed = 0; + size_t written = base64_decode(&out[0], + reinterpret_cast<const char*>(&in[0]), + position, + consumed, + true, + checking != FULL_CHECK); + + send(out, written); + + const bool not_full_bytes = consumed != position; - if(left_over) - { - SecureVector<byte> remainder(4); - copy_mem(&remainder[0], &in[start_of_last_block], left_over); - decode(&remainder[0], &out[0]); - send(out, ((left_over == 1) ? (1) : (left_over - 1))); - } - } position = 0; + + if(not_full_bytes) + throw std::invalid_argument("Base64_Decoder: Input not full bytes"); } } diff --git a/src/filters/codec_filt/b64_filt.h b/src/filters/codec_filt/b64_filt.h index df3896666..afff53f30 100644 --- a/src/filters/codec_filt/b64_filt.h +++ b/src/filters/codec_filt/b64_filt.h @@ -47,7 +47,7 @@ class BOTAN_DLL Base64_Encoder : public Filter const size_t line_length; const bool trailing_newline; - SecureVector<byte> in, out; + MemoryVector<byte> in, out; size_t position, out_position; }; @@ -78,14 +78,8 @@ class BOTAN_DLL Base64_Decoder : public Filter */ Base64_Decoder(Decoder_Checking checking = NONE); private: - static void decode(const byte input[4], byte output[3]); - static bool is_valid(byte c); - - void decode_and_send(const byte[], size_t); - void handle_bad_char(byte); - const Decoder_Checking checking; - SecureVector<byte> in, out; + MemoryVector<byte> in, out; size_t position; }; diff --git a/src/filters/codec_filt/hex_filt.h b/src/filters/codec_filt/hex_filt.h index cfbb818d3..0dc38c804 100644 --- a/src/filters/codec_filt/hex_filt.h +++ b/src/filters/codec_filt/hex_filt.h @@ -49,7 +49,7 @@ class BOTAN_DLL Hex_Encoder : public Filter const Case casing; const size_t line_length; - SecureVector<byte> in, out; + MemoryVector<byte> in, out; size_t position, counter; }; @@ -72,7 +72,7 @@ class BOTAN_DLL Hex_Decoder : public Filter Hex_Decoder(Decoder_Checking checking = NONE); private: const Decoder_Checking checking; - SecureVector<byte> in, out; + MemoryVector<byte> in, out; size_t position; }; diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw_512/bmw_512.cpp index 40338fdf0..40338fdf0 100644 --- a/src/hash/bmw/bmw_512.cpp +++ b/src/hash/bmw_512/bmw_512.cpp diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw_512/bmw_512.h index 474b607bb..474b607bb 100644 --- a/src/hash/bmw/bmw_512.h +++ b/src/hash/bmw_512/bmw_512.h diff --git a/src/hash/bmw/info.txt b/src/hash/bmw_512/info.txt index 7170223d7..7170223d7 100644 --- a/src/hash/bmw/info.txt +++ b/src/hash/bmw_512/info.txt diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index 7a42ca867..f5daaadb2 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -1,6 +1,6 @@ /* * SHA-160 -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2008,2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -11,6 +11,8 @@ namespace Botan { +namespace SHA1_F { + namespace { /* @@ -51,11 +53,15 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) } +} + /* * SHA-160 Compression Function */ void SHA_160::compress_n(const byte input[], size_t blocks) { + using namespace SHA1_F; + u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4]; diff --git a/src/hash/sha1_sse2/sha1_sse2.cpp b/src/hash/sha1_sse2/sha1_sse2.cpp index e890967c6..f96afd9ce 100644 --- a/src/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/hash/sha1_sse2/sha1_sse2.cpp @@ -1,6 +1,6 @@ /* * SHA-1 using SSE2 -* (C) 2009-2010 Jack Lloyd +* (C) 2009-2011 Jack Lloyd * * Distributed under the terms of the Botan license * @@ -14,6 +14,8 @@ namespace Botan { +namespace SHA1_SSE2_F { + namespace { /* @@ -146,11 +148,15 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) } +} + /* * SHA-160 Compression Function using SSE for message expansion */ void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks) { + using namespace SHA1_SSE2_F; + const __m128i K00_19 = _mm_set1_epi32(0x5A827999); const __m128i K20_39 = _mm_set1_epi32(0x6ED9EBA1); const __m128i K40_59 = _mm_set1_epi32(0x8F1BBCDC); @@ -323,4 +329,7 @@ void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks) #undef GET_P_32 } +#undef prep00_15 +#undef prep + } diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp index f85968e84..571bf9c0b 100644 --- a/src/hash/skein/skein_512.cpp +++ b/src/hash/skein/skein_512.cpp @@ -184,6 +184,8 @@ Skein_512::Skein_512(size_t arg_output_bits, std::string Skein_512::name() const { + if(personalization != "") + return "Skein-512(" + to_string(output_bits) + "," + personalization + ")"; return "Skein-512(" + to_string(output_bits) + ")"; } diff --git a/src/kdf/ssl_prf/info.txt b/src/kdf/prf_ssl3/info.txt index 0ef297119..0ef297119 100644 --- a/src/kdf/ssl_prf/info.txt +++ b/src/kdf/prf_ssl3/info.txt diff --git a/src/kdf/ssl_prf/prf_ssl3.cpp b/src/kdf/prf_ssl3/prf_ssl3.cpp index 72cf023e2..72cf023e2 100644 --- a/src/kdf/ssl_prf/prf_ssl3.cpp +++ b/src/kdf/prf_ssl3/prf_ssl3.cpp diff --git a/src/kdf/ssl_prf/prf_ssl3.h b/src/kdf/prf_ssl3/prf_ssl3.h index b07454be2..b07454be2 100644 --- a/src/kdf/ssl_prf/prf_ssl3.h +++ b/src/kdf/prf_ssl3/prf_ssl3.h diff --git a/src/kdf/tls_prf/info.txt b/src/kdf/prf_tls/info.txt index 9531a6a83..9531a6a83 100644 --- a/src/kdf/tls_prf/info.txt +++ b/src/kdf/prf_tls/info.txt diff --git a/src/kdf/tls_prf/prf_tls.cpp b/src/kdf/prf_tls/prf_tls.cpp index 2b57cdd25..2b57cdd25 100644 --- a/src/kdf/tls_prf/prf_tls.cpp +++ b/src/kdf/prf_tls/prf_tls.cpp diff --git a/src/kdf/tls_prf/prf_tls.h b/src/kdf/prf_tls/prf_tls.h index 5237f17c0..5237f17c0 100644 --- a/src/kdf/tls_prf/prf_tls.h +++ b/src/kdf/prf_tls/prf_tls.h diff --git a/src/kdf/x942_prf/info.txt b/src/kdf/prf_x942/info.txt index e51aafd08..e51aafd08 100644 --- a/src/kdf/x942_prf/info.txt +++ b/src/kdf/prf_x942/info.txt diff --git a/src/kdf/x942_prf/prf_x942.cpp b/src/kdf/prf_x942/prf_x942.cpp index fc31effe4..fc31effe4 100644 --- a/src/kdf/x942_prf/prf_x942.cpp +++ b/src/kdf/prf_x942/prf_x942.cpp diff --git a/src/kdf/x942_prf/prf_x942.h b/src/kdf/prf_x942/prf_x942.h index e6093eda6..e6093eda6 100644 --- a/src/kdf/x942_prf/prf_x942.h +++ b/src/kdf/prf_x942/prf_x942.h diff --git a/src/libstate/policy.cpp b/src/libstate/policy.cpp index 05ca6f807..f91eed1d8 100644 --- a/src/libstate/policy.cpp +++ b/src/libstate/policy.cpp @@ -302,6 +302,16 @@ void set_default_dl_groups(Library_State& config) "Nf2tRM/S10+SCL4lj/MklDMo9nMpwP//////////" "-----END X942 DH PARAMETERS-----"); + config.set("dl", "modp/srp/1024", + "-----BEGIN X942 DH PARAMETERS-----" + "MIIBCgKBgQDurwq5rbON1pwz+Ar6j8XoYHJhh3X/PAueojFMnCVldtZ033SW6oHT" + "ODtIE9aSxuDg1djiULmL5I5JXB1gidrRXcfXtGFU1rbOjvStabFdSYJVmyl7zxiF" + "xSn1ZmYOV+xo7bw8BXJswC/Uy/SXbqqa/VE4/oN2Q1ufxh0vwOsG4wIBAgKBgHdX" + "hVzW2cbrThn8BX1H4vQwOTDDuv+eBc9RGKZOErK7azpvukt1QOmcHaQJ60ljcHBq" + "7HEoXMXyRySuDrBE7Wiu4+vaMKprW2dHela02K6kwSrNlL3njELilPqzMwcr9jR2" + "3h4CuTZgF+pl+ku3VU1+qJx/Qbshrc/jDpfgdYNx" + "-----END X942 DH PARAMETERS-----"); + config.set("dl", "modp/ietf/1536", "-----BEGIN X942 DH PARAMETERS-----" "MIIBigKBwQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5si" @@ -330,6 +340,21 @@ void set_default_dl_groups(Library_State& config) "2uKu+DemKWTvFeX7SqwLjBzKpL51SrVyiukTDEx9AogKuUctRVZVNH//////////" "-----END X942 DH PARAMETERS-----"); + config.set("dl", "modp/srp/2048", + "-----BEGIN X942 DH PARAMETERS-----" + "MIICDAKCAQEArGvbQTJKmpvxZt5eE4lYL69ytmUZh+4H/DGSlD21YFCjcynLtKCZ" + "7YGT4HV3Z6E91SMSq0sDMQ3Nf0ip2gT9UOgIOWntt2ewz2CVF5oWOrNmGgX71fqq" + "6CkYqZYvC5O4Vfl5k+yXXuqoDXQK2/T/dHNZ0EHVwz6nHSgeRGsUdzvKl7Q6I/uA" + "Fna9IHpDbGSB8dK5B4cXRhpbnTLmiPh3SFRFI7UksNV9Xqd6J3XS7PoDLPvb9S+z" + "eGFgJ5AE5Xrmr4dOcwPOUymczAQce8MI2CpWmPOo0MOCca41+Onb+7aUtcgD2J96" + "5DXeI21SX1R1m2XjcvzWjvIPpxEfnkr/cwIBAgKCAQBWNe2gmSVNTfizby8JxKwX" + "17lbMozD9wP+GMlKHtqwKFG5lOXaUEz2wMnwOruz0J7qkYlVpYGYhua/pFTtAn6o" + "dAQctPbbs9hnsEqLzQsdWbMNAv3q/VV0FIxUyxeFydwq/LzJ9kuvdVQGugVt+n+6" + "OazoIOrhn1OOlA8iNYo7neVL2h0R/cALO16QPSG2MkD46VyDw4ujDS3OmXNEfDuk" + "KiKR2pJYar6vU70Tuul2fQGWfe36l9m8MLATyAJyvXNXw6c5gecplM5mAg494YRs" + "FStMedRoYcE41xr8dO3920pa5AHsT71yGu8RtqkvqjrNsvG5fmtHeQfTiI/PJX+5" + "-----END X942 DH PARAMETERS-----"); + config.set("dl", "modp/ietf/3072", "-----BEGIN X942 DH PARAMETERS-----" "MIIDDAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb" diff --git a/src/mac/cmac/cmac.cpp b/src/mac/cmac/cmac.cpp index 7db597fff..baf22f4e8 100644 --- a/src/mac/cmac/cmac.cpp +++ b/src/mac/cmac/cmac.cpp @@ -16,7 +16,7 @@ namespace Botan { SecureVector<byte> CMAC::poly_double(const MemoryRegion<byte>& in, byte polynomial) { - const bool do_xor = (in[0] & 0x80) ? true : false; + const byte poly_xor = (in[0] & 0x80) ? polynomial : 0; SecureVector<byte> out = in; @@ -28,8 +28,7 @@ SecureVector<byte> CMAC::poly_double(const MemoryRegion<byte>& in, carry = (temp >> 7); } - if(do_xor) - out[out.size()-1] ^= polynomial; + out[out.size()-1] ^= poly_xor; return out; } diff --git a/src/math/bigint/bigint.cpp b/src/math/bigint/bigint.cpp index 6ee5a75e3..e2e062f2d 100644 --- a/src/math/bigint/bigint.cpp +++ b/src/math/bigint/bigint.cpp @@ -1,6 +1,6 @@ /* * BigInt Base -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -26,8 +26,8 @@ BigInt::BigInt(u64bit n) const size_t limbs_needed = sizeof(u64bit) / sizeof(word); reg.resize(4*limbs_needed); - for(size_t j = 0; j != limbs_needed; ++j) - reg[j] = ((n >> (j*MP_WORD_BITS)) & MP_WORD_MASK); + for(size_t i = 0; i != limbs_needed; ++i) + reg[i] = ((n >> (i*MP_WORD_BITS)) & MP_WORD_MASK); } /* @@ -171,16 +171,35 @@ u32bit BigInt::get_substring(size_t offset, size_t length) const throw Invalid_Argument("BigInt::get_substring: Substring size too big"); u64bit piece = 0; - for(size_t j = 0; j != 8; ++j) - piece = (piece << 8) | byte_at((offset / 8) + (7-j)); + for(size_t i = 0; i != 8; ++i) + { + const byte part = byte_at((offset / 8) + (7-i)); + piece = (piece << 8) | part; + } - u64bit mask = (1 << length) - 1; - size_t shift = (offset % 8); + const u64bit mask = (static_cast<u64bit>(1) << length) - 1; + const size_t shift = (offset % 8); return static_cast<u32bit>((piece >> shift) & mask); } /* +* Convert this number to a u32bit, if possible +*/ +u32bit BigInt::to_u32bit() const + { + if(is_negative()) + throw Encoding_Error("BigInt::to_u32bit: Number is negative"); + if(bits() >= 32) + throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert"); + + u32bit out = 0; + for(u32bit j = 0; j != 4; ++j) + out = (out << 8) | byte_at(3-j); + return out; + } + +/* * Set bit number n */ void BigInt::set_bit(size_t n) @@ -214,8 +233,8 @@ void BigInt::mask_bits(size_t n) const word mask = (static_cast<word>(1) << (n % MP_WORD_BITS)) - 1; if(top_word < size()) - for(size_t j = top_word + 1; j != size(); ++j) - reg[j] = 0; + for(size_t i = top_word + 1; i != size(); ++i) + reg[i] = 0; reg[top_word] &= mask; } @@ -321,8 +340,8 @@ BigInt BigInt::abs() const void BigInt::binary_encode(byte output[]) const { const size_t sig_bytes = bytes(); - for(size_t j = 0; j != sig_bytes; ++j) - output[sig_bytes-j-1] = byte_at(j); + for(size_t i = 0; i != sig_bytes; ++i) + output[sig_bytes-i-1] = byte_at(i); } /* @@ -335,14 +354,15 @@ void BigInt::binary_decode(const byte buf[], size_t length) clear(); reg.resize(round_up<size_t>((length / WORD_BYTES) + 1, 8)); - for(size_t j = 0; j != length / WORD_BYTES; ++j) + for(size_t i = 0; i != length / WORD_BYTES; ++i) { - size_t top = length - WORD_BYTES*j; - for(size_t k = WORD_BYTES; k > 0; --k) - reg[j] = (reg[j] << 8) | buf[top - k]; + const size_t top = length - WORD_BYTES*i; + for(size_t j = WORD_BYTES; j > 0; --j) + reg[i] = (reg[i] << 8) | buf[top - j]; } - for(size_t j = 0; j != length % WORD_BYTES; ++j) - reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[j]; + + for(size_t i = 0; i != length % WORD_BYTES; ++i) + reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[i]; } /* diff --git a/src/math/bigint/bigint.h b/src/math/bigint/bigint.h index 12a7f1701..87c7cb766 100644 --- a/src/math/bigint/bigint.h +++ b/src/math/bigint/bigint.h @@ -218,6 +218,13 @@ class BOTAN_DLL BigInt u32bit get_substring(size_t offset, size_t length) const; /** + * Convert this value into a u32bit, if it is in the range + * [0 ... 2**32-1], or otherwise throw an exception. + * @result the value as a u32bit if conversion is possible + */ + u32bit to_u32bit() const; + + /** * @param n the offset to get a byte from * @result byte at offset n */ diff --git a/src/math/numbertheory/curve_gfp.h b/src/math/ec_gfp/curve_gfp.h index 1ab803ec9..9867f82fe 100644 --- a/src/math/numbertheory/curve_gfp.h +++ b/src/math/ec_gfp/curve_gfp.h @@ -2,7 +2,7 @@ * Elliptic curves over GF(p) * * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2010 Jack Lloyd +* 2010-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -11,7 +11,6 @@ #define BOTAN_GFP_CURVE_H__ #include <botan/numthry.h> -#include <botan/reducer.h> namespace Botan { @@ -34,18 +33,15 @@ class BOTAN_DLL CurveGFp * @param b second coefficient */ CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) : - p(p), a(a), b(b), reducer_p(p) + p(p), a(a), b(b), p_words(p.sig_words()) { - r = 1; - r <<= p.sig_words() * BOTAN_MP_WORD_BITS; + BigInt r(BigInt::Power2, p_words * BOTAN_MP_WORD_BITS); - r_inv = inverse_mod(r, p); + p_dash = (((r * inverse_mod(r, p)) - 1) / p).word_at(0); - p_dash = (((r * r_inv) - 1) / p).word_at(0); - - a_r = reducer_p.multiply(a, r); - - p_words = p.sig_words(); + r2 = (r * r) % p; + a_r = (a * r) % p; + b_r = (b * r) % p; } // CurveGFp(const CurveGFp& other) = default; @@ -68,19 +64,19 @@ class BOTAN_DLL CurveGFp const BigInt& get_p() const { return p; } /** - * @return Montgomery parameter r + * @return Montgomery parameter r^2 % p */ - const BigInt& get_r() const { return r; } + const BigInt& get_r2() const { return r2; } /** - * @return Montgomery parameter r^-1 + * @return a * r mod p */ - const BigInt& get_r_inv() const { return r_inv; } + const BigInt& get_a_r() const { return a_r; } /** - * @return a * r mod p + * @return b * r mod p */ - const BigInt& get_a_r() const { return a_r; } + const BigInt& get_b_r() const { return b_r; } /** * @return Montgomery parameter p-dash @@ -93,23 +89,22 @@ class BOTAN_DLL CurveGFp size_t get_p_words() const { return p_words; } /** - * @return modular reducer for p - */ - const Modular_Reducer& mod_p() const { return reducer_p; } - - /** * swaps the states of *this and other, does not throw * @param other curve to swap values with */ void swap(CurveGFp& other) { + std::swap(p, other.p); + std::swap(a, other.a); std::swap(b, other.b); - std::swap(p, other.p); - std::swap(reducer_p, other.reducer_p); - std::swap(r, other.r); - std::swap(r_inv, other.r_inv); + std::swap(a_r, other.a_r); + std::swap(b_r, other.b_r); + + std::swap(p_words, other.p_words); + + std::swap(r2, other.r2); std::swap(p_dash, other.p_dash); } @@ -120,7 +115,11 @@ class BOTAN_DLL CurveGFp */ bool operator==(const CurveGFp& other) const { - return (p == other.p && a == other.a && b == other.b); + /* + Relies on choice of R, but that is fixed by constructor based + on size of p + */ + return (p == other.p && a_r == other.a_r && b_r == other.b_r); } private: @@ -130,10 +129,8 @@ class BOTAN_DLL CurveGFp size_t p_words; // cache of p.sig_words() // Montgomery parameters - BigInt r, r_inv, a_r; + BigInt r2, a_r, b_r; word p_dash; - - Modular_Reducer reducer_p; }; /** diff --git a/src/math/ec_gfp/info.txt b/src/math/ec_gfp/info.txt new file mode 100644 index 000000000..e6ee1d6bf --- /dev/null +++ b/src/math/ec_gfp/info.txt @@ -0,0 +1,16 @@ +define EC_CURVE_GFP + +load_on auto + +<header:public> +curve_gfp.h +point_gfp.h +</header:public> + +<source> +point_gfp.cpp +</source> + +<requires> +numbertheory +</requires> diff --git a/src/math/numbertheory/point_gfp.cpp b/src/math/ec_gfp/point_gfp.cpp index fab731d29..7ac6b4141 100644 --- a/src/math/numbertheory/point_gfp.cpp +++ b/src/math/ec_gfp/point_gfp.cpp @@ -1,40 +1,37 @@ /* -* Arithmetic for point groups of elliptic curves over GF(p) +* Point arithmetic on elliptic curves over GF(p) * * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2008-2010 Jack Lloyd +* 2008-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ #include <botan/point_gfp.h> #include <botan/numthry.h> +#include <botan/reducer.h> #include <botan/internal/mp_core.h> namespace Botan { PointGFp::PointGFp(const CurveGFp& curve) : - curve(curve), - coord_x(0), - coord_y(curve.get_r()), - coord_z(0) + curve(curve), ws(2 * (curve.get_p_words() + 2)) { + coord_x = 0; + coord_y = monty_mult(1, curve.get_r2()); + coord_z = 0; } PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) : - curve(curve) + curve(curve), ws(2 * (curve.get_p_words() + 2)) { - const Modular_Reducer& mod_p = curve.mod_p(); - - coord_x = mod_p.multiply(curve.get_r(), x); - coord_y = mod_p.multiply(curve.get_r(), y); - coord_z = mod_p.reduce(curve.get_r()); + coord_x = monty_mult(x, curve.get_r2()); + coord_y = monty_mult(y, curve.get_r2()); + coord_z = monty_mult(1, curve.get_r2()); } // Montgomery multiplication -void PointGFp::monty_mult(BigInt& z, - const BigInt& x, const BigInt& y, - MemoryRegion<word>& workspace) const +void PointGFp::monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const { //assert(&z != &x && &z != &y); @@ -52,19 +49,15 @@ void PointGFp::monty_mult(BigInt& z, z_reg.resize(2*p_size+1); zeroise(z_reg); - bigint_mul(&z_reg[0], z_reg.size(), - &workspace[0], - x.data(), x.size(), x.sig_words(), - y.data(), y.size(), y.sig_words()); - - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - p.data(), p_size, p_dash); + bigint_monty_mul(&z_reg[0], z_reg.size(), + x.data(), x.size(), x.sig_words(), + y.data(), y.size(), y.sig_words(), + p.data(), p_size, p_dash, + &ws[0]); } // Montgomery squaring -void PointGFp::monty_sqr(BigInt& z, const BigInt& x, - MemoryRegion<word>& workspace) const +void PointGFp::monty_sqr(BigInt& z, const BigInt& x) const { //assert(&z != &x); @@ -82,17 +75,14 @@ void PointGFp::monty_sqr(BigInt& z, const BigInt& x, z_reg.resize(2*p_size+1); zeroise(z_reg); - bigint_sqr(&z[0], z.size(), - &workspace[0], - x.data(), x.size(), x.sig_words()); - - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - p.data(), p_size, p_dash); + bigint_monty_sqr(&z_reg[0], z_reg.size(), + x.data(), x.size(), x.sig_words(), + p.data(), p_size, p_dash, + &ws[0]); } // Point addition -void PointGFp::add(const PointGFp& rhs, Workspace& workspace) +void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) { if(is_zero()) { @@ -106,9 +96,6 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace) const BigInt& p = curve.get_p(); - MemoryRegion<word>& ws = workspace.ws_monty; - std::vector<BigInt>& ws_bn = workspace.ws_bn; - BigInt& rhs_z2 = ws_bn[0]; BigInt& U1 = ws_bn[1]; BigInt& S1 = ws_bn[2]; @@ -120,17 +107,13 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace) BigInt& H = ws_bn[6]; BigInt& r = ws_bn[7]; - BigInt& x = ws_bn[8]; - BigInt& y = ws_bn[9]; - BigInt& z = ws_bn[10]; + monty_sqr(rhs_z2, rhs.coord_z); + monty_mult(U1, coord_x, rhs_z2); + monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2)); - monty_sqr(rhs_z2, rhs.coord_z, ws); - monty_mult(U1, coord_x, rhs_z2, ws); - monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2, ws), ws); - - monty_sqr(lhs_z2, coord_z, ws); - monty_mult(U2, rhs.coord_x, lhs_z2, ws); - monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2, ws), ws); + monty_sqr(lhs_z2, coord_z); + monty_mult(U2, rhs.coord_x, lhs_z2); + monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2)); H = U2; H -= U1; @@ -146,7 +129,7 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace) { if(r.is_zero()) { - mult2(workspace); + mult2(ws_bn); return; } @@ -154,36 +137,32 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace) return; } - monty_sqr(U2, H, ws); + monty_sqr(U2, H); - monty_mult(S2, U2, H, ws); + monty_mult(S2, U2, H); - U2 = monty_mult(U1, U2, ws); + U2 = monty_mult(U1, U2); - monty_sqr(x, r, ws); - x -= S2; - x -= (U2 << 1); - while(x.is_negative()) - x += p; + monty_sqr(coord_x, r); + coord_x -= S2; + coord_x -= (U2 << 1); + while(coord_x.is_negative()) + coord_x += p; - U2 -= x; + U2 -= coord_x; if(U2.is_negative()) U2 += p; - monty_mult(y, r, U2, ws); - y -= monty_mult(S1, S2, ws); - if(y.is_negative()) - y += p; - - monty_mult(z, monty_mult(coord_z, rhs.coord_z, ws), H, ws); + monty_mult(coord_y, r, U2); + coord_y -= monty_mult(S1, S2); + if(coord_y.is_negative()) + coord_y += p; - coord_x = x; - coord_y = y; - coord_z = z; + monty_mult(coord_z, monty_mult(coord_z, rhs.coord_z), H); } // *this *= 2 -void PointGFp::mult2(Workspace& workspace) +void PointGFp::mult2(std::vector<BigInt>& ws_bn) { if(is_zero()) return; @@ -195,9 +174,6 @@ void PointGFp::mult2(Workspace& workspace) const BigInt& p = curve.get_p(); - MemoryRegion<word>& ws = workspace.ws_monty; - std::vector<BigInt>& ws_bn = workspace.ws_bn; - BigInt& y_2 = ws_bn[0]; BigInt& S = ws_bn[1]; BigInt& z4 = ws_bn[2]; @@ -208,27 +184,27 @@ void PointGFp::mult2(Workspace& workspace) BigInt& y = ws_bn[7]; BigInt& z = ws_bn[8]; - monty_sqr(y_2, coord_y, ws); + monty_sqr(y_2, coord_y); - monty_mult(S, coord_x, y_2, ws); + monty_mult(S, coord_x, y_2); S <<= 2; // * 4 while(S >= p) S -= p; - monty_sqr(z4, monty_sqr(coord_z, ws), ws); - monty_mult(a_z4, curve.get_a_r(), z4, ws); + monty_sqr(z4, monty_sqr(coord_z)); + monty_mult(a_z4, curve.get_a_r(), z4); - M = 3 * monty_sqr(coord_x, ws); + M = 3 * monty_sqr(coord_x); M += a_z4; while(M >= p) M -= p; - monty_sqr(x, M, ws); + monty_sqr(x, M); x -= (S << 1); while(x.is_negative()) x += p; - monty_sqr(U, y_2, ws); + monty_sqr(U, y_2); U <<= 3; while(U >= p) U -= p; @@ -237,12 +213,12 @@ void PointGFp::mult2(Workspace& workspace) while(S.is_negative()) S += p; - monty_mult(y, M, S, ws); + monty_mult(y, M, S); y -= U; if(y.is_negative()) y += p; - monty_mult(z, coord_y, coord_z, ws); + monty_mult(z, coord_y, coord_z); z <<= 1; if(z >= p) z -= p; @@ -255,7 +231,7 @@ void PointGFp::mult2(Workspace& workspace) // arithmetic operators PointGFp& PointGFp::operator+=(const PointGFp& rhs) { - Workspace ws(curve.get_p_words()); + std::vector<BigInt> ws(9); add(rhs, ws); return *this; } @@ -278,6 +254,39 @@ PointGFp& PointGFp::operator*=(const BigInt& scalar) return *this; } +PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1, + const PointGFp& p2, const BigInt& z2) + { + const PointGFp p3 = p1 + p2; + + PointGFp H(p1.curve); // create as zero + size_t bits_left = std::max(z1.bits(), z2.bits()); + + std::vector<BigInt> ws(9); + + while(bits_left) + { + H.mult2(ws); + + const bool z1_b = z1.get_bit(bits_left - 1); + const bool z2_b = z2.get_bit(bits_left - 1); + + if(z1_b == true && z2_b == true) + H.add(p3, ws); + else if(z1_b) + H.add(p1, ws); + else if(z2_b) + H.add(p2, ws); + + --bits_left; + } + + if(z1.is_negative() != z2.is_negative()) + H.negate(); + + return H; + } + PointGFp operator*(const BigInt& scalar, const PointGFp& point) { const CurveGFp& curve = point.get_curve(); @@ -285,7 +294,7 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point) if(scalar.is_zero()) return PointGFp(curve); // zero point - PointGFp::Workspace ws(curve.get_p_words()); + std::vector<BigInt> ws(9); if(scalar.abs() <= 2) // special cases for small values { @@ -304,6 +313,38 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point) const size_t scalar_bits = scalar.bits(); +#if 0 + + PointGFp x1 = PointGFp(curve); + PointGFp x2 = point; + + size_t bits_left = scalar_bits; + + // Montgomery Ladder + while(bits_left) + { + const bool bit_set = scalar.get_bit(bits_left - 1); + + if(bit_set) + { + x1.add(x2, ws); + x2.mult2(ws); + } + else + { + x2.add(x1, ws); + x1.mult2(ws); + } + + --bits_left; + } + + if(scalar.is_negative()) + x1.negate(); + + return x1; + +#else const size_t window_size = 4; std::vector<PointGFp> Ps(1 << window_size); @@ -345,6 +386,7 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point) H.negate(); return H; +#endif } BigInt PointGFp::get_affine_x() const @@ -352,23 +394,13 @@ BigInt PointGFp::get_affine_x() const if(is_zero()) throw Illegal_Transformation("Cannot convert zero point to affine"); - const Modular_Reducer& mod_p = curve.mod_p(); - -#if 1 - BigInt x = mod_p.multiply(curve.get_r_inv(), coord_x); - BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z); - - BigInt z2 = mod_p.square(z); - return mod_p.multiply(x, inverse_mod(z2, curve.get_p())); -#else - - SecureVector<word> ws(2 * (curve.get_p_words() + 2)); + const BigInt& r2 = curve.get_r2(); - BigInt z2 = monty_sqr(coord_z, ws); + BigInt z2 = monty_sqr(coord_z); z2 = inverse_mod(z2, curve.get_p()); - z2 = mod_p.multiply(z2, curve.get_r()); - return monty_mult(coord_x, z2, ws); -#endif + + z2 = monty_mult(z2, r2); + return monty_mult(coord_x, z2); } BigInt PointGFp::get_affine_y() const @@ -376,23 +408,12 @@ BigInt PointGFp::get_affine_y() const if(is_zero()) throw Illegal_Transformation("Cannot convert zero point to affine"); - const Modular_Reducer& mod_p = curve.mod_p(); + const BigInt& r2 = curve.get_r2(); -#if 1 - BigInt y = mod_p.multiply(curve.get_r_inv(), coord_y); - BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z); - - BigInt z3 = mod_p.cube(z); - return mod_p.multiply(y, inverse_mod(z3, curve.get_p())); -#else - - SecureVector<word> ws(2 * (curve.get_p_words() + 2)); - - BigInt z3 = monty_mult(coord_z, monty_sqr(coord_z, ws), ws); + BigInt z3 = monty_mult(coord_z, monty_sqr(coord_z)); z3 = inverse_mod(z3, curve.get_p()); - z3 = mod_p.multiply(z3, curve.get_r()); - return monty_mult(coord_y, z3, ws); -#endif + z3 = monty_mult(z3, r2); + return monty_mult(coord_y, z3); } bool PointGFp::on_the_curve() const @@ -407,31 +428,28 @@ bool PointGFp::on_the_curve() const if(is_zero()) return true; - const Modular_Reducer& mod_p = curve.mod_p(); + BigInt y2 = monty_mult(monty_sqr(coord_y), 1); + BigInt x3 = monty_mult(coord_x, monty_sqr(coord_x)); - BigInt x = mod_p.multiply(curve.get_r_inv(), coord_x); - BigInt y = mod_p.multiply(curve.get_r_inv(), coord_y); - BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z); + BigInt ax = monty_mult(coord_x, curve.get_a_r()); - BigInt y2 = mod_p.square(y); - BigInt x3 = mod_p.cube(x); + const BigInt& b_r = curve.get_b_r(); - BigInt ax = mod_p.multiply(x, curve.get_a()); + BigInt z2 = monty_sqr(coord_z); - if(z == 1) + if(coord_z == z2) // Is z equal to 1 (in Montgomery form)? { - if(mod_p.reduce(x3 + ax + curve.get_b()) != y2) + if(y2 != monty_mult(x3 + ax + b_r, 1)) return false; } - BigInt z2 = mod_p.square(z); - BigInt z3 = mod_p.multiply(z, z2); + BigInt z3 = monty_mult(coord_z, z2); - BigInt ax_z4 = mod_p.multiply(mod_p.multiply(z3, z), ax); + BigInt ax_z4 = monty_mult(ax, monty_sqr(z2)); - BigInt b_z6 = mod_p.multiply(curve.get_b(), mod_p.square(z3)); + BigInt b_z6 = monty_mult(b_r, monty_sqr(z3)); - if(y2 != mod_p.reduce(x3 + ax_z4 + b_z6)) + if(y2 != monty_mult(x3 + ax_z4 + b_z6, 1)) return false; return true; @@ -444,6 +462,7 @@ void PointGFp::swap(PointGFp& other) coord_x.swap(other.coord_x); coord_y.swap(other.coord_y); coord_z.swap(other.coord_z); + ws.swap(other.ws); } bool PointGFp::operator==(const PointGFp& other) const diff --git a/src/math/numbertheory/point_gfp.h b/src/math/ec_gfp/point_gfp.h index 35ec6d503..b2b6fe2f0 100644 --- a/src/math/numbertheory/point_gfp.h +++ b/src/math/ec_gfp/point_gfp.h @@ -1,8 +1,8 @@ /* -* Arithmetic for point groups of elliptic curves over GF(p) +* Point arithmetic on elliptic curves over GF(p) * * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2008-2010 Jack Lloyd +* 2008-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -99,6 +99,18 @@ class BOTAN_DLL PointGFp friend BOTAN_DLL PointGFp operator*(const BigInt& scalar, const PointGFp& point); /** + * Multiexponentiation + * @param p1 a point + * @param z1 a scalar + * @param p2 a point + * @param z2 a scalar + * @result (p1 * z1 + p2 * z2) + */ + friend BOTAN_DLL PointGFp multi_exponentiate( + const PointGFp& p1, const BigInt& z1, + const PointGFp& p2, const BigInt& z2); + + /** * Negate this point * @return *this */ @@ -153,27 +165,16 @@ class BOTAN_DLL PointGFp bool operator==(const PointGFp& other) const; private: - class Workspace - { - public: - Workspace(size_t p_words) : - ws_monty(2*(p_words+2)), ws_bn(12) {} - - SecureVector<word> ws_monty; - std::vector<BigInt> ws_bn; - }; - /** * Montgomery multiplication/reduction * @param x first multiplicand * @param y second multiplicand * @param workspace temp space */ - BigInt monty_mult(const BigInt& x, const BigInt& y, - MemoryRegion<word>& workspace) const + BigInt monty_mult(const BigInt& x, const BigInt& y) const { BigInt result; - monty_mult(result, x, y, workspace); + monty_mult(result, x, y); return result; } @@ -183,22 +184,17 @@ class BOTAN_DLL PointGFp * @param z output * @param x first multiplicand * @param y second multiplicand - * @param workspace temp space */ - void monty_mult(BigInt& z, - const BigInt& x, const BigInt& y, - MemoryRegion<word>& workspace) const; + void monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const; /** * Montgomery squaring/reduction * @param x multiplicand - * @param workspace temp space */ - BigInt monty_sqr(const BigInt& x, - MemoryRegion<word>& workspace) const + BigInt monty_sqr(const BigInt& x) const { BigInt result; - monty_sqr(result, x, workspace); + monty_sqr(result, x); return result; } @@ -207,24 +203,24 @@ class BOTAN_DLL PointGFp * @warning z cannot alias x * @param z output * @param x multiplicand - * @param workspace temp space */ - void monty_sqr(BigInt& z, const BigInt& x, - MemoryRegion<word>& workspace) const; + void monty_sqr(BigInt& z, const BigInt& x) const; /** * Point addition + * @param workspace temp space, at least 11 elements */ - void add(const PointGFp& other, Workspace& workspace); + void add(const PointGFp& other, std::vector<BigInt>& workspace); /** * Point doubling - * @param workspace temp space + * @param workspace temp space, at least 9 elements */ - void mult2(Workspace& workspace); + void mult2(std::vector<BigInt>& workspace); CurveGFp curve; BigInt coord_x, coord_y, coord_z; + mutable SecureVector<word> ws; // workspace for Montgomery }; // relational operators diff --git a/src/math/mp/info.txt b/src/math/mp/info.txt index 911093699..bf7f40d3c 100644 --- a/src/math/mp/info.txt +++ b/src/math/mp/info.txt @@ -4,6 +4,8 @@ define BIGINT_MP mp_asm.cpp mp_comba.cpp mp_karat.cpp +mp_monty.cpp +mp_mulop.cpp mp_misc.cpp mp_shift.cpp </source> @@ -18,6 +20,4 @@ mp_core.h <requires> mp_x86_64|mp_msvc64|mp_asm64|mp_x86_32|mp_x86_32_msvc|mp_generic -monty_generic -mulop_generic </requires> diff --git a/src/math/mp/monty_generic/info.txt b/src/math/mp/monty_generic/info.txt deleted file mode 100644 index cd05ccdc0..000000000 --- a/src/math/mp/monty_generic/info.txt +++ /dev/null @@ -1,5 +0,0 @@ -load_on dep - -<source> -mp_monty.cpp -</source> diff --git a/src/math/mp/monty_generic/mp_monty.cpp b/src/math/mp/monty_generic/mp_monty.cpp deleted file mode 100644 index d7f7e0306..000000000 --- a/src/math/mp/monty_generic/mp_monty.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -* Montgomery Reduction -* (C) 1999-2010 Jack Lloyd -* 2006 Luca Piccarreta -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/mp_core.h> -#include <botan/internal/mp_asm.h> -#include <botan/internal/mp_asmi.h> -#include <botan/mem_ops.h> - -namespace Botan { - -extern "C" { - -/* -* Montgomery Reduction Algorithm -*/ -void bigint_monty_redc(word z[], size_t z_size, - word ws[], - const word x[], size_t x_size, - word u) - { - const size_t blocks_of_8 = x_size - (x_size % 8); - - for(size_t i = 0; i != x_size; ++i) - { - word* z_i = z + i; - - const word y = z_i[0] * u; - - /* - bigint_linmul3(ws, x, x_size, y); - bigint_add2(z_i, z_size - i, ws, x_size+1); - */ - word carry = 0; - - for(size_t j = 0; j != blocks_of_8; j += 8) - carry = word8_madd3(z_i + j, x + j, y, carry); - - for(size_t j = blocks_of_8; j != x_size; ++j) - z_i[j] = word_madd3(x[j], y, z_i[j], &carry); - - word z_sum = z_i[x_size] + carry; - carry = (z_sum < z_i[x_size]); - z_i[x_size] = z_sum; - - // Note: not constant time - for(size_t j = x_size + 1; carry && j != z_size - i; ++j) - { - ++z_i[j]; - carry = !z_i[j]; - } - } - - word borrow = 0; - for(size_t i = 0; i != x_size; ++i) - ws[i] = word_sub(z[x_size + i], x[i], &borrow); - - ws[x_size] = word_sub(z[x_size+x_size], 0, &borrow); - - copy_mem(ws + x_size + 1, z + x_size, x_size + 1); - - copy_mem(z, ws + borrow*(x_size+1), x_size + 1); - clear_mem(z + x_size + 1, z_size - x_size - 1); - } - -} - -} diff --git a/src/math/mp/mp_asm.cpp b/src/math/mp/mp_asm.cpp index d164c1d33..3ba52c4b1 100644 --- a/src/math/mp/mp_asm.cpp +++ b/src/math/mp/mp_asm.cpp @@ -67,7 +67,8 @@ word bigint_add3_nc(word z[], const word x[], size_t x_size, */ void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size) { - x[x_size] += bigint_add2_nc(x, x_size, y, y_size); + if(bigint_add2_nc(x, x_size, y, y_size)) + x[x_size] += 1; } /* diff --git a/src/math/mp/mp_asm64/info.txt b/src/math/mp/mp_asm64/info.txt index 42363e8b0..9af7c4ae7 100644 --- a/src/math/mp/mp_asm64/info.txt +++ b/src/math/mp/mp_asm64/info.txt @@ -20,5 +20,5 @@ sparc64 # win, so it's probably worth using elsewhere. <cc> gcc -sunwspro +sunstudio </cc> diff --git a/src/math/mp/mp_comba.cpp b/src/math/mp/mp_comba.cpp index 2770d3f0a..99dcda176 100644 --- a/src/math/mp/mp_comba.cpp +++ b/src/math/mp/mp_comba.cpp @@ -1,6 +1,6 @@ /* * Comba Multiplication and Squaring -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -19,30 +19,30 @@ void bigint_comba_sqr4(word z[8], const word x[4]) { word w2 = 0, w1 = 0, w0 = 0; - word3_muladd(&w2, &w1, &w0, x[0], x[0]); - z[0] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[0], x[1]); - z[1] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[0], x[2]); - word3_muladd(&w2, &w1, &w0, x[1], x[1]); - z[2] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; - word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); - z[3] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[1], x[3]); - word3_muladd(&w2, &w1, &w0, x[2], x[2]); - z[4] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[2], x[3]); - z[5] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, x[3], x[3]); - z[6] = w0; - z[7] = w1; + word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; + z[ 7] = w1; } /* @@ -52,36 +52,36 @@ void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) { word w2 = 0, w1 = 0, w0 = 0; - word3_muladd(&w2, &w1, &w0, x[0], y[0]); - z[0] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; - word3_muladd(&w2, &w1, &w0, x[0], y[1]); - word3_muladd(&w2, &w1, &w0, x[1], y[0]); - z[1] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; - word3_muladd(&w2, &w1, &w0, x[0], y[2]); - word3_muladd(&w2, &w1, &w0, x[1], y[1]); - word3_muladd(&w2, &w1, &w0, x[2], y[0]); - z[2] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, x[0], y[3]); - word3_muladd(&w2, &w1, &w0, x[1], y[2]); - word3_muladd(&w2, &w1, &w0, x[2], y[1]); - word3_muladd(&w2, &w1, &w0, x[3], y[0]); - z[3] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; - word3_muladd(&w2, &w1, &w0, x[1], y[3]); - word3_muladd(&w2, &w1, &w0, x[2], y[2]); - word3_muladd(&w2, &w1, &w0, x[3], y[1]); - z[4] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + z[ 4] = w1; w1 = 0; - word3_muladd(&w2, &w1, &w0, x[2], y[3]); - word3_muladd(&w2, &w1, &w0, x[3], y[2]); - z[5] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + z[ 5] = w2; w2 = 0; - word3_muladd(&w2, &w1, &w0, x[3], y[3]); - z[6] = w0; - z[7] = w1; + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + z[ 6] = w0; + z[ 7] = w1; } /* @@ -91,49 +91,49 @@ void bigint_comba_sqr6(word z[12], const word x[6]) { word w2 = 0, w1 = 0, w0 = 0; - word3_muladd(&w2, &w1, &w0, x[0], x[0]); - z[0] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[0], x[1]); - z[1] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[0], x[2]); - word3_muladd(&w2, &w1, &w0, x[1], x[1]); - z[2] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; - word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); - z[3] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[0], x[4]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[3]); - word3_muladd(&w2, &w1, &w0, x[2], x[2]); - z[4] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[0], x[5]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[4]); - word3_muladd_2(&w2, &w1, &w0, x[2], x[3]); - z[5] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; - word3_muladd_2(&w2, &w1, &w0, x[1], x[5]); - word3_muladd_2(&w2, &w1, &w0, x[2], x[4]); - word3_muladd(&w2, &w1, &w0, x[3], x[3]); - z[6] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[2], x[5]); - word3_muladd_2(&w2, &w1, &w0, x[3], x[4]); - z[7] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); + z[ 7] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[3], x[5]); - word3_muladd(&w2, &w1, &w0, x[4], x[4]); - z[8] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]); + z[ 8] = w2; w2 = 0; - word3_muladd_2(&w2, &w1, &w0, x[4], x[5]); - z[9] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); + z[ 9] = w0; w0 = 0; - word3_muladd(&w2, &w1, &w0, x[5], x[5]); - z[10] = w0; - z[11] = w1; + word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]); + z[10] = w1; + z[11] = w2; } /* @@ -143,64 +143,64 @@ void bigint_comba_mul6(word z[12], const word x[6], const word y[6]) { word w2 = 0, w1 = 0, w0 = 0; - word3_muladd(&w2, &w1, &w0, x[0], y[0]); - z[0] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[1]); - word3_muladd(&w2, &w1, &w0, x[1], y[0]); - z[1] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[2]); - word3_muladd(&w2, &w1, &w0, x[1], y[1]); - word3_muladd(&w2, &w1, &w0, x[2], y[0]); - z[2] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[3]); - word3_muladd(&w2, &w1, &w0, x[1], y[2]); - word3_muladd(&w2, &w1, &w0, x[2], y[1]); - word3_muladd(&w2, &w1, &w0, x[3], y[0]); - z[3] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[4]); - word3_muladd(&w2, &w1, &w0, x[1], y[3]); - word3_muladd(&w2, &w1, &w0, x[2], y[2]); - word3_muladd(&w2, &w1, &w0, x[3], y[1]); - word3_muladd(&w2, &w1, &w0, x[4], y[0]); - z[4] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[5]); - word3_muladd(&w2, &w1, &w0, x[1], y[4]); - word3_muladd(&w2, &w1, &w0, x[2], y[3]); - word3_muladd(&w2, &w1, &w0, x[3], y[2]); - word3_muladd(&w2, &w1, &w0, x[4], y[1]); - word3_muladd(&w2, &w1, &w0, x[5], y[0]); - z[5] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[1], y[5]); - word3_muladd(&w2, &w1, &w0, x[2], y[4]); - word3_muladd(&w2, &w1, &w0, x[3], y[3]); - word3_muladd(&w2, &w1, &w0, x[4], y[2]); - word3_muladd(&w2, &w1, &w0, x[5], y[1]); - z[6] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[2], y[5]); - word3_muladd(&w2, &w1, &w0, x[3], y[4]); - word3_muladd(&w2, &w1, &w0, x[4], y[3]); - word3_muladd(&w2, &w1, &w0, x[5], y[2]); - z[7] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[3], y[5]); - word3_muladd(&w2, &w1, &w0, x[4], y[4]); - word3_muladd(&w2, &w1, &w0, x[5], y[3]); - z[8] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[4], y[5]); - word3_muladd(&w2, &w1, &w0, x[5], y[4]); - z[9] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[5], y[5]); - z[10] = w0; - z[11] = w1; + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); + z[ 5] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); + z[ 6] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); + z[ 7] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); + z[ 8] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); + z[ 9] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); + z[10] = w1; + z[11] = w2; } /* @@ -210,72 +210,72 @@ void bigint_comba_sqr8(word z[16], const word x[8]) { word w2 = 0, w1 = 0, w0 = 0; - word3_muladd(&w2, &w1, &w0, x[0], x[0]); - z[0] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[0], x[1]); - z[1] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[0], x[2]); - word3_muladd(&w2, &w1, &w0, x[1], x[1]); - z[2] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[0], x[3]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[2]); - z[3] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[0], x[4]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[3]); - word3_muladd(&w2, &w1, &w0, x[2], x[2]); - z[4] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[0], x[5]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[4]); - word3_muladd_2(&w2, &w1, &w0, x[2], x[3]); - z[5] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[0], x[6]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[5]); - word3_muladd_2(&w2, &w1, &w0, x[2], x[4]); - word3_muladd(&w2, &w1, &w0, x[3], x[3]); - z[6] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[0], x[7]); - word3_muladd_2(&w2, &w1, &w0, x[1], x[6]); - word3_muladd_2(&w2, &w1, &w0, x[2], x[5]); - word3_muladd_2(&w2, &w1, &w0, x[3], x[4]); - z[7] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[1], x[7]); - word3_muladd_2(&w2, &w1, &w0, x[2], x[6]); - word3_muladd_2(&w2, &w1, &w0, x[3], x[5]); - word3_muladd(&w2, &w1, &w0, x[4], x[4]); - z[8] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[2], x[7]); - word3_muladd_2(&w2, &w1, &w0, x[3], x[6]); - word3_muladd_2(&w2, &w1, &w0, x[4], x[5]); - z[9] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[3], x[7]); - word3_muladd_2(&w2, &w1, &w0, x[4], x[6]); - word3_muladd(&w2, &w1, &w0, x[5], x[5]); - z[10] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[4], x[7]); - word3_muladd_2(&w2, &w1, &w0, x[5], x[6]); - z[11] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[5], x[7]); - word3_muladd(&w2, &w1, &w0, x[6], x[6]); - z[12] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[6], x[7]); - z[13] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[7], x[7]); - z[14] = w0; - z[15] = w1; + word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); + z[ 3] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]); + z[ 6] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); + z[ 7] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]); + z[ 8] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); + word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); + word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); + z[ 9] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]); + z[10] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); + z[11] = w2; w2 = 0; + + word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]); + z[12] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); + z[13] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]); + z[14] = w2; + z[15] = w0; } /* @@ -285,100 +285,100 @@ void bigint_comba_mul8(word z[16], const word x[8], const word y[8]) { word w2 = 0, w1 = 0, w0 = 0; - word3_muladd(&w2, &w1, &w0, x[0], y[0]); - z[0] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[1]); - word3_muladd(&w2, &w1, &w0, x[1], y[0]); - z[1] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[2]); - word3_muladd(&w2, &w1, &w0, x[1], y[1]); - word3_muladd(&w2, &w1, &w0, x[2], y[0]); - z[2] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[3]); - word3_muladd(&w2, &w1, &w0, x[1], y[2]); - word3_muladd(&w2, &w1, &w0, x[2], y[1]); - word3_muladd(&w2, &w1, &w0, x[3], y[0]); - z[3] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[4]); - word3_muladd(&w2, &w1, &w0, x[1], y[3]); - word3_muladd(&w2, &w1, &w0, x[2], y[2]); - word3_muladd(&w2, &w1, &w0, x[3], y[1]); - word3_muladd(&w2, &w1, &w0, x[4], y[0]); - z[4] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[5]); - word3_muladd(&w2, &w1, &w0, x[1], y[4]); - word3_muladd(&w2, &w1, &w0, x[2], y[3]); - word3_muladd(&w2, &w1, &w0, x[3], y[2]); - word3_muladd(&w2, &w1, &w0, x[4], y[1]); - word3_muladd(&w2, &w1, &w0, x[5], y[0]); - z[5] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[6]); - word3_muladd(&w2, &w1, &w0, x[1], y[5]); - word3_muladd(&w2, &w1, &w0, x[2], y[4]); - word3_muladd(&w2, &w1, &w0, x[3], y[3]); - word3_muladd(&w2, &w1, &w0, x[4], y[2]); - word3_muladd(&w2, &w1, &w0, x[5], y[1]); - word3_muladd(&w2, &w1, &w0, x[6], y[0]); - z[6] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[0], y[7]); - word3_muladd(&w2, &w1, &w0, x[1], y[6]); - word3_muladd(&w2, &w1, &w0, x[2], y[5]); - word3_muladd(&w2, &w1, &w0, x[3], y[4]); - word3_muladd(&w2, &w1, &w0, x[4], y[3]); - word3_muladd(&w2, &w1, &w0, x[5], y[2]); - word3_muladd(&w2, &w1, &w0, x[6], y[1]); - word3_muladd(&w2, &w1, &w0, x[7], y[0]); - z[7] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[1], y[7]); - word3_muladd(&w2, &w1, &w0, x[2], y[6]); - word3_muladd(&w2, &w1, &w0, x[3], y[5]); - word3_muladd(&w2, &w1, &w0, x[4], y[4]); - word3_muladd(&w2, &w1, &w0, x[5], y[3]); - word3_muladd(&w2, &w1, &w0, x[6], y[2]); - word3_muladd(&w2, &w1, &w0, x[7], y[1]); - z[8] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[2], y[7]); - word3_muladd(&w2, &w1, &w0, x[3], y[6]); - word3_muladd(&w2, &w1, &w0, x[4], y[5]); - word3_muladd(&w2, &w1, &w0, x[5], y[4]); - word3_muladd(&w2, &w1, &w0, x[6], y[3]); - word3_muladd(&w2, &w1, &w0, x[7], y[2]); - z[9] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[3], y[7]); - word3_muladd(&w2, &w1, &w0, x[4], y[6]); - word3_muladd(&w2, &w1, &w0, x[5], y[5]); - word3_muladd(&w2, &w1, &w0, x[6], y[4]); - word3_muladd(&w2, &w1, &w0, x[7], y[3]); - z[10] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[4], y[7]); - word3_muladd(&w2, &w1, &w0, x[5], y[6]); - word3_muladd(&w2, &w1, &w0, x[6], y[5]); - word3_muladd(&w2, &w1, &w0, x[7], y[4]); - z[11] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[5], y[7]); - word3_muladd(&w2, &w1, &w0, x[6], y[6]); - word3_muladd(&w2, &w1, &w0, x[7], y[5]); - z[12] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[6], y[7]); - word3_muladd(&w2, &w1, &w0, x[7], y[6]); - z[13] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[7], y[7]); - z[14] = w0; - z[15] = w1; + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); + z[ 0] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); + z[ 5] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); + z[ 6] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); + z[ 7] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); + z[ 8] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]); + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); + z[ 9] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); + z[10] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); + z[11] = w2; w2 = 0; + + word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]); + word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]); + word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]); + z[12] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); + z[13] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); + z[14] = w2; + z[15] = w0; } /* @@ -389,70 +389,70 @@ void bigint_comba_sqr16(word z[32], const word x[16]) word w2 = 0, w1 = 0, w0 = 0; word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]); - z[ 0] = w0; w0 = w1; w1 = w2; w2 = 0; + z[ 0] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 1]); - z[ 1] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]); + z[ 1] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 1], x[ 1]); - z[ 2] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]); + z[ 2] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]); word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]); - z[ 3] = w0; w0 = w1; w1 = w2; w2 = 0; + z[ 3] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 4]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 2], x[ 2]); - z[ 4] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]); + z[ 4] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 4]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 3]); - z[ 5] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]); + z[ 5] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]); word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]); word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]); word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]); - z[ 6] = w0; w0 = w1; w1 = w2; w2 = 0; + z[ 6] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 5]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 4]); - z[ 7] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]); + z[ 7] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 6]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 4], x[ 4]); - z[ 8] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]); + z[ 8] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 9]); word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]); word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]); word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]); word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]); - z[ 9] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 5], x[ 5]); - z[10] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 7]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 6]); - z[11] = w0; w0 = w1; w1 = w2; w2 = 0; + z[ 9] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 9]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]); + z[10] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 9]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]); + z[11] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[ 0], x[12]); word3_muladd_2(&w2, &w1, &w0, x[ 1], x[11]); @@ -461,26 +461,26 @@ void bigint_comba_sqr16(word z[32], const word x[16]) word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]); word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]); word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]); - z[12] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 8]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 7]); - z[13] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 0], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 9]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 7], x[ 7]); - z[14] = w0; w0 = w1; w1 = w2; w2 = 0; + z[12] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 0], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 9]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]); + z[13] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 0], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 1], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 9]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]); + z[14] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[ 0], x[15]); word3_muladd_2(&w2, &w1, &w0, x[ 1], x[14]); @@ -490,26 +490,26 @@ void bigint_comba_sqr16(word z[32], const word x[16]) word3_muladd_2(&w2, &w1, &w0, x[ 5], x[10]); word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 9]); word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]); - z[15] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 1], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 8], x[ 8]); - z[16] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 2], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 3], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[10]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[ 9]); - z[17] = w0; w0 = w1; w1 = w2; w2 = 0; + z[15] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 1], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 2], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 3], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[10]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 8], x[ 8]); + z[16] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 2], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 3], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 4], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[11]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[10]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[ 9]); + z[17] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[ 3], x[15]); word3_muladd_2(&w2, &w1, &w0, x[ 4], x[14]); @@ -518,70 +518,70 @@ void bigint_comba_sqr16(word z[32], const word x[16]) word3_muladd_2(&w2, &w1, &w0, x[ 7], x[11]); word3_muladd_2(&w2, &w1, &w0, x[ 8], x[10]); word3_muladd(&w2, &w1, &w0, x[ 9], x[ 9]); - z[18] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 4], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[11]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[10]); - z[19] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd_2(&w2, &w1, &w0, x[ 5], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 6], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[12]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[11]); - word3_muladd(&w2, &w1, &w0, x[10], x[10]); - z[20] = w0; w0 = w1; w1 = w2; w2 = 0; + z[18] = w0; w0 = 0; + + word3_muladd_2(&w0, &w2, &w1, x[ 4], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 5], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 6], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[12]); + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[11]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[10]); + z[19] = w1; w1 = 0; + + word3_muladd_2(&w1, &w0, &w2, x[ 5], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 6], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[ 7], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[12]); + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[11]); + word3_muladd(&w1, &w0, &w2, x[10], x[10]); + z[20] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[ 6], x[15]); word3_muladd_2(&w2, &w1, &w0, x[ 7], x[14]); word3_muladd_2(&w2, &w1, &w0, x[ 8], x[13]); word3_muladd_2(&w2, &w1, &w0, x[ 9], x[12]); word3_muladd_2(&w2, &w1, &w0, x[10], x[11]); - z[21] = w0; w0 = w1; w1 = w2; w2 = 0; + z[21] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[ 7], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[12]); - word3_muladd(&w2, &w1, &w0, x[11], x[11]); - z[22] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[ 7], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[ 8], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[ 9], x[13]); + word3_muladd_2(&w0, &w2, &w1, x[10], x[12]); + word3_muladd(&w0, &w2, &w1, x[11], x[11]); + z[22] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[ 8], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[ 9], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[10], x[13]); - word3_muladd_2(&w2, &w1, &w0, x[11], x[12]); - z[23] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[ 8], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[ 9], x[14]); + word3_muladd_2(&w1, &w0, &w2, x[10], x[13]); + word3_muladd_2(&w1, &w0, &w2, x[11], x[12]); + z[23] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[ 9], x[15]); word3_muladd_2(&w2, &w1, &w0, x[10], x[14]); word3_muladd_2(&w2, &w1, &w0, x[11], x[13]); word3_muladd(&w2, &w1, &w0, x[12], x[12]); - z[24] = w0; w0 = w1; w1 = w2; w2 = 0; + z[24] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[10], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[11], x[14]); - word3_muladd_2(&w2, &w1, &w0, x[12], x[13]); - z[25] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[10], x[15]); + word3_muladd_2(&w0, &w2, &w1, x[11], x[14]); + word3_muladd_2(&w0, &w2, &w1, x[12], x[13]); + z[25] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[11], x[15]); - word3_muladd_2(&w2, &w1, &w0, x[12], x[14]); - word3_muladd(&w2, &w1, &w0, x[13], x[13]); - z[26] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[11], x[15]); + word3_muladd_2(&w1, &w0, &w2, x[12], x[14]); + word3_muladd(&w1, &w0, &w2, x[13], x[13]); + z[26] = w2; w2 = 0; word3_muladd_2(&w2, &w1, &w0, x[12], x[15]); word3_muladd_2(&w2, &w1, &w0, x[13], x[14]); - z[27] = w0; w0 = w1; w1 = w2; w2 = 0; + z[27] = w0; w0 = 0; - word3_muladd_2(&w2, &w1, &w0, x[13], x[15]); - word3_muladd(&w2, &w1, &w0, x[14], x[14]); - z[28] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w0, &w2, &w1, x[13], x[15]); + word3_muladd(&w0, &w2, &w1, x[14], x[14]); + z[28] = w1; w1 = 0; - word3_muladd_2(&w2, &w1, &w0, x[14], x[15]); - z[29] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd_2(&w1, &w0, &w2, x[14], x[15]); + z[29] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[15], x[15]); z[30] = w0; @@ -596,37 +596,37 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) word w2 = 0, w1 = 0, w0 = 0; word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]); - z[0] = w0; w0 = w1; w1 = w2; w2 = 0; + z[ 0] = w0; w0 = 0; - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 0]); - z[1] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]); + z[ 1] = w1; w1 = 0; - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 0]); - z[2] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]); + z[ 2] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]); word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]); word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]); word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]); - z[3] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 0]); - z[4] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 0]); - z[5] = w0; w0 = w1; w1 = w2; w2 = 0; + z[ 3] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]); + z[ 4] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]); + z[ 5] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]); word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]); @@ -635,28 +635,28 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]); word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]); word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]); - z[6] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 0]); - z[7] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 0]); - z[8] = w0; w0 = w1; w1 = w2; w2 = 0; + z[ 6] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]); + z[ 7] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]); + z[ 8] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[ 0], y[ 9]); word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]); @@ -668,34 +668,34 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]); word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]); word3_muladd(&w2, &w1, &w0, x[ 9], y[ 0]); - z[9] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 0]); - z[10] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 0]); - z[11] = w0; w0 = w1; w1 = w2; w2 = 0; + z[ 9] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 0]); + z[10] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 0]); + z[11] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[ 0], y[12]); word3_muladd(&w2, &w1, &w0, x[ 1], y[11]); @@ -710,40 +710,40 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) word3_muladd(&w2, &w1, &w0, x[10], y[ 2]); word3_muladd(&w2, &w1, &w0, x[11], y[ 1]); word3_muladd(&w2, &w1, &w0, x[12], y[ 0]); - z[12] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 0]); - z[13] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 0], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 1], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 1]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 0]); - z[14] = w0; w0 = w1; w1 = w2; w2 = 0; + z[12] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 0], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 1], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 1]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 0]); + z[13] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 0], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 1], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 2], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 2]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 1]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 0]); + z[14] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[ 0], y[15]); word3_muladd(&w2, &w1, &w0, x[ 1], y[14]); @@ -761,40 +761,40 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) word3_muladd(&w2, &w1, &w0, x[13], y[ 2]); word3_muladd(&w2, &w1, &w0, x[14], y[ 1]); word3_muladd(&w2, &w1, &w0, x[15], y[ 0]); - z[15] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 1], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 2], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 2]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 1]); - z[16] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 2], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 3], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 4], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[10]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 4]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 3]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 2]); - z[17] = w0; w0 = w1; w1 = w2; w2 = 0; + z[15] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 1], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 2], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 3], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 4], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[10]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 4]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 3]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 2]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 1]); + z[16] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 2], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 3], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 4], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 5], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[11]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[10]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[10], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 5]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 4]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 3]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 2]); + z[17] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[ 3], y[15]); word3_muladd(&w2, &w1, &w0, x[ 4], y[14]); @@ -809,34 +809,34 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) word3_muladd(&w2, &w1, &w0, x[13], y[ 5]); word3_muladd(&w2, &w1, &w0, x[14], y[ 4]); word3_muladd(&w2, &w1, &w0, x[15], y[ 3]); - z[18] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 4], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 5], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[11]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[10]); - word3_muladd(&w2, &w1, &w0, x[10], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 5]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 4]); - z[19] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 5], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 6], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 7], y[13]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[12]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[11]); - word3_muladd(&w2, &w1, &w0, x[10], y[10]); - word3_muladd(&w2, &w1, &w0, x[11], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[12], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 7]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 6]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 5]); - z[20] = w0; w0 = w1; w1 = w2; w2 = 0; + z[18] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 4], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 5], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 6], y[13]); + word3_muladd(&w0, &w2, &w1, x[ 7], y[12]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[11]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[10]); + word3_muladd(&w0, &w2, &w1, x[10], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[11], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[12], y[ 7]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 6]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 5]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 4]); + z[19] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 5], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 6], y[14]); + word3_muladd(&w1, &w0, &w2, x[ 7], y[13]); + word3_muladd(&w1, &w0, &w2, x[ 8], y[12]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[11]); + word3_muladd(&w1, &w0, &w2, x[10], y[10]); + word3_muladd(&w1, &w0, &w2, x[11], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[12], y[ 8]); + word3_muladd(&w1, &w0, &w2, x[13], y[ 7]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 6]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 5]); + z[20] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[ 6], y[15]); word3_muladd(&w2, &w1, &w0, x[ 7], y[14]); @@ -848,28 +848,28 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) word3_muladd(&w2, &w1, &w0, x[13], y[ 8]); word3_muladd(&w2, &w1, &w0, x[14], y[ 7]); word3_muladd(&w2, &w1, &w0, x[15], y[ 6]); - z[21] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 7], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 8], y[14]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[13]); - word3_muladd(&w2, &w1, &w0, x[10], y[12]); - word3_muladd(&w2, &w1, &w0, x[11], y[11]); - word3_muladd(&w2, &w1, &w0, x[12], y[10]); - word3_muladd(&w2, &w1, &w0, x[13], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 8]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 7]); - z[22] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[ 8], y[15]); - word3_muladd(&w2, &w1, &w0, x[ 9], y[14]); - word3_muladd(&w2, &w1, &w0, x[10], y[13]); - word3_muladd(&w2, &w1, &w0, x[11], y[12]); - word3_muladd(&w2, &w1, &w0, x[12], y[11]); - word3_muladd(&w2, &w1, &w0, x[13], y[10]); - word3_muladd(&w2, &w1, &w0, x[14], y[ 9]); - word3_muladd(&w2, &w1, &w0, x[15], y[ 8]); - z[23] = w0; w0 = w1; w1 = w2; w2 = 0; + z[21] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[ 7], y[15]); + word3_muladd(&w0, &w2, &w1, x[ 8], y[14]); + word3_muladd(&w0, &w2, &w1, x[ 9], y[13]); + word3_muladd(&w0, &w2, &w1, x[10], y[12]); + word3_muladd(&w0, &w2, &w1, x[11], y[11]); + word3_muladd(&w0, &w2, &w1, x[12], y[10]); + word3_muladd(&w0, &w2, &w1, x[13], y[ 9]); + word3_muladd(&w0, &w2, &w1, x[14], y[ 8]); + word3_muladd(&w0, &w2, &w1, x[15], y[ 7]); + z[22] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[ 8], y[15]); + word3_muladd(&w1, &w0, &w2, x[ 9], y[14]); + word3_muladd(&w1, &w0, &w2, x[10], y[13]); + word3_muladd(&w1, &w0, &w2, x[11], y[12]); + word3_muladd(&w1, &w0, &w2, x[12], y[11]); + word3_muladd(&w1, &w0, &w2, x[13], y[10]); + word3_muladd(&w1, &w0, &w2, x[14], y[ 9]); + word3_muladd(&w1, &w0, &w2, x[15], y[ 8]); + z[23] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[ 9], y[15]); word3_muladd(&w2, &w1, &w0, x[10], y[14]); @@ -878,37 +878,37 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) word3_muladd(&w2, &w1, &w0, x[13], y[11]); word3_muladd(&w2, &w1, &w0, x[14], y[10]); word3_muladd(&w2, &w1, &w0, x[15], y[ 9]); - z[24] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[10], y[15]); - word3_muladd(&w2, &w1, &w0, x[11], y[14]); - word3_muladd(&w2, &w1, &w0, x[12], y[13]); - word3_muladd(&w2, &w1, &w0, x[13], y[12]); - word3_muladd(&w2, &w1, &w0, x[14], y[11]); - word3_muladd(&w2, &w1, &w0, x[15], y[10]); - z[25] = w0; w0 = w1; w1 = w2; w2 = 0; - - word3_muladd(&w2, &w1, &w0, x[11], y[15]); - word3_muladd(&w2, &w1, &w0, x[12], y[14]); - word3_muladd(&w2, &w1, &w0, x[13], y[13]); - word3_muladd(&w2, &w1, &w0, x[14], y[12]); - word3_muladd(&w2, &w1, &w0, x[15], y[11]); - z[26] = w0; w0 = w1; w1 = w2; w2 = 0; + z[24] = w0; w0 = 0; + + word3_muladd(&w0, &w2, &w1, x[10], y[15]); + word3_muladd(&w0, &w2, &w1, x[11], y[14]); + word3_muladd(&w0, &w2, &w1, x[12], y[13]); + word3_muladd(&w0, &w2, &w1, x[13], y[12]); + word3_muladd(&w0, &w2, &w1, x[14], y[11]); + word3_muladd(&w0, &w2, &w1, x[15], y[10]); + z[25] = w1; w1 = 0; + + word3_muladd(&w1, &w0, &w2, x[11], y[15]); + word3_muladd(&w1, &w0, &w2, x[12], y[14]); + word3_muladd(&w1, &w0, &w2, x[13], y[13]); + word3_muladd(&w1, &w0, &w2, x[14], y[12]); + word3_muladd(&w1, &w0, &w2, x[15], y[11]); + z[26] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[12], y[15]); word3_muladd(&w2, &w1, &w0, x[13], y[14]); word3_muladd(&w2, &w1, &w0, x[14], y[13]); word3_muladd(&w2, &w1, &w0, x[15], y[12]); - z[27] = w0; w0 = w1; w1 = w2; w2 = 0; + z[27] = w0; w0 = 0; - word3_muladd(&w2, &w1, &w0, x[13], y[15]); - word3_muladd(&w2, &w1, &w0, x[14], y[14]); - word3_muladd(&w2, &w1, &w0, x[15], y[13]); - z[28] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w0, &w2, &w1, x[13], y[15]); + word3_muladd(&w0, &w2, &w1, x[14], y[14]); + word3_muladd(&w0, &w2, &w1, x[15], y[13]); + z[28] = w1; w1 = 0; - word3_muladd(&w2, &w1, &w0, x[14], y[15]); - word3_muladd(&w2, &w1, &w0, x[15], y[14]); - z[29] = w0; w0 = w1; w1 = w2; w2 = 0; + word3_muladd(&w1, &w0, &w2, x[14], y[15]); + word3_muladd(&w1, &w0, &w2, x[15], y[14]); + z[29] = w2; w2 = 0; word3_muladd(&w2, &w1, &w0, x[15], y[15]); z[30] = w0; diff --git a/src/math/mp/mp_core.h b/src/math/mp/mp_core.h index e1692006e..82bdbad53 100644 --- a/src/math/mp/mp_core.h +++ b/src/math/mp/mp_core.h @@ -77,19 +77,35 @@ void bigint_simple_sqr(word z[], const word x[], size_t x_size); void bigint_linmul2(word x[], size_t x_size, word y); void bigint_linmul3(word z[], const word x[], size_t x_size, word y); -/* +/** * Montgomery Reduction -* @param z integer to reduce (also output in first x_size+1 words) -* @param z_size size of z (should be >= 2*x_size+1) -* @param workspace array of at least 2*(x_size+1) words -* @param x modulus -* @param x_size size of x -* @param u Montgomery value +* @param z integer to reduce (also output in first p_size+1 words) +* @param z_size size of z (should be >= 2*p_size+1) +* @param p modulus +* @param p_size size of p +* @param p_dash Montgomery value +* @param workspace array of at least 2*(p_size+1) words */ void bigint_monty_redc(word z[], size_t z_size, - word workspace[], - const word x[], size_t x_size, - word u); + const word p[], size_t p_size, word p_dash, + word workspace[]); + +/* +* Montgomery Multiplication +*/ +void bigint_monty_mul(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word y[], size_t y_size, size_t y_sw, + const word p[], size_t p_size, word p_dash, + word workspace[]); + +/* +* Montgomery Squaring +*/ +void bigint_monty_sqr(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word p[], size_t p_size, word p_dash, + word workspace[]); /* * Division operation @@ -124,8 +140,7 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]); void bigint_comba_sqr4(word out[8], const word in[4]); void bigint_comba_sqr6(word out[12], const word in[6]); void bigint_comba_sqr8(word out[16], const word in[8]); -void bigint_comba_sqr8(word out[32], const word in[16]); -void bigint_comba_sqr16(word out[64], const word in[32]); +void bigint_comba_sqr16(word out[32], const word in[16]); } diff --git a/src/math/mp/mp_generic/mp_asm.h b/src/math/mp/mp_generic/mp_asm.h index ee46e1aa9..7c18343ef 100644 --- a/src/math/mp/mp_generic/mp_asm.h +++ b/src/math/mp/mp_generic/mp_asm.h @@ -14,7 +14,7 @@ #if (BOTAN_MP_WORD_BITS == 8) typedef Botan::u16bit dword; #elif (BOTAN_MP_WORD_BITS == 16) - typedef Botan::size_t dword; + typedef Botan::u32bit dword; #elif (BOTAN_MP_WORD_BITS == 32) typedef Botan::u64bit dword; #elif (BOTAN_MP_WORD_BITS == 64) diff --git a/src/math/mp/mp_monty.cpp b/src/math/mp/mp_monty.cpp new file mode 100644 index 000000000..d37fb5844 --- /dev/null +++ b/src/math/mp/mp_monty.cpp @@ -0,0 +1,99 @@ +/* +* Montgomery Reduction +* (C) 1999-2011 Jack Lloyd +* 2006 Luca Piccarreta +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/mp_core.h> +#include <botan/internal/mp_asm.h> +#include <botan/internal/mp_asmi.h> +#include <botan/mem_ops.h> + +namespace Botan { + +extern "C" { + +/* +* Montgomery Reduction Algorithm +*/ +void bigint_monty_redc(word z[], size_t z_size, + const word p[], size_t p_size, + word p_dash, word ws[]) + { + const size_t blocks_of_8 = p_size - (p_size % 8); + + for(size_t i = 0; i != p_size; ++i) + { + word* z_i = z + i; + + const word y = z_i[0] * p_dash; + + /* + bigint_linmul3(ws, p, p_size, y); + bigint_add2(z_i, z_size - i, ws, p_size+1); + */ + + word carry = 0; + + for(size_t j = 0; j != blocks_of_8; j += 8) + carry = word8_madd3(z_i + j, p + j, y, carry); + + for(size_t j = blocks_of_8; j != p_size; ++j) + z_i[j] = word_madd3(p[j], y, z_i[j], &carry); + + word z_sum = z_i[p_size] + carry; + carry = (z_sum < z_i[p_size]); + z_i[p_size] = z_sum; + + for(size_t j = p_size + 1; carry && j != z_size - i; ++j) + { + ++z_i[j]; + carry = !z_i[j]; + } + } + + word borrow = 0; + for(size_t i = 0; i != p_size; ++i) + ws[i] = word_sub(z[p_size + i], p[i], &borrow); + + ws[p_size] = word_sub(z[p_size+p_size], 0, &borrow); + + copy_mem(ws + p_size + 1, z + p_size, p_size + 1); + + copy_mem(z, ws + borrow*(p_size+1), p_size + 1); + clear_mem(z + p_size + 1, z_size - p_size - 1); + } + +void bigint_monty_mul(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word y[], size_t y_size, size_t y_sw, + const word p[], size_t p_size, word p_dash, + word ws[]) + { + bigint_mul(&z[0], z_size, &ws[0], + &x[0], x_size, x_sw, + &y[0], y_size, y_sw); + + bigint_monty_redc(&z[0], z_size, + &p[0], p_size, p_dash, + &ws[0]); + } + +void bigint_monty_sqr(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word p[], size_t p_size, word p_dash, + word ws[]) + { + bigint_sqr(&z[0], z_size, &ws[0], + &x[0], x_size, x_sw); + + bigint_monty_redc(&z[0], z_size, + &p[0], p_size, p_dash, + &ws[0]); + } + +} + +} diff --git a/src/math/mp/mulop_generic/mp_mulop.cpp b/src/math/mp/mp_mulop.cpp index e6a8ba891..e6a8ba891 100644 --- a/src/math/mp/mulop_generic/mp_mulop.cpp +++ b/src/math/mp/mp_mulop.cpp diff --git a/src/math/mp/mulop_generic/info.txt b/src/math/mp/mulop_generic/info.txt deleted file mode 100644 index 548d0f44b..000000000 --- a/src/math/mp/mulop_generic/info.txt +++ /dev/null @@ -1,5 +0,0 @@ -load_on dep - -<source> -mp_mulop.cpp -</source> diff --git a/src/math/numbertheory/info.txt b/src/math/numbertheory/info.txt index 18349ef78..0c6a9aefc 100644 --- a/src/math/numbertheory/info.txt +++ b/src/math/numbertheory/info.txt @@ -1,11 +1,9 @@ -load_on auto - define BIGINT_MATH +load_on auto + <header:public> -curve_gfp.h numthry.h -point_gfp.h pow_mod.h reducer.h </header:public> @@ -20,7 +18,6 @@ jacobi.cpp make_prm.cpp mp_numth.cpp numthry.cpp -point_gfp.cpp pow_mod.cpp powm_fw.cpp powm_mnt.cpp diff --git a/src/math/numbertheory/numthry.cpp b/src/math/numbertheory/numthry.cpp index 8018c1d2d..c7896c17a 100644 --- a/src/math/numbertheory/numthry.cpp +++ b/src/math/numbertheory/numthry.cpp @@ -1,6 +1,6 @@ /* * Number Theory Functions -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -20,7 +20,7 @@ namespace { class MillerRabin_Test { public: - bool passes_test(const BigInt& nonce); + bool is_witness(const BigInt& nonce); MillerRabin_Test(const BigInt& num); private: BigInt n, r, n_minus_1; @@ -30,26 +30,32 @@ class MillerRabin_Test }; /* -* Miller-Rabin Test +* Miller-Rabin Test, as described in Handbook of Applied Cryptography +* section 4.24 */ -bool MillerRabin_Test::passes_test(const BigInt& a) +bool MillerRabin_Test::is_witness(const BigInt& a) { if(a < 2 || a >= n_minus_1) throw Invalid_Argument("Bad size for nonce in Miller-Rabin test"); BigInt y = pow_mod(a); if(y == 1 || y == n_minus_1) - return true; + return false; for(size_t i = 1; i != s; ++i) { y = reducer.square(y); - if(y == 1) - return false; - if(y == n_minus_1) + if(y == 1) // found a non-trivial square root return true; + + if(y == n_minus_1) // -1, trivial square root, so give up + return false; } + + if(y != n_minus_1) // fails Fermat test + return true; + return false; } @@ -297,7 +303,7 @@ bool primality_test(const BigInt& n, while(nonce < 2 || nonce >= (n-1)) nonce.randomize(rng, NONCE_BITS); - if(!mr.passes_test(nonce)) + if(mr.is_witness(nonce)) return false; } return true; diff --git a/src/math/numbertheory/pow_mod.cpp b/src/math/numbertheory/pow_mod.cpp index a66a1f7df..bf6b29275 100644 --- a/src/math/numbertheory/pow_mod.cpp +++ b/src/math/numbertheory/pow_mod.cpp @@ -118,7 +118,12 @@ size_t Power_Mod::window_bits(size_t exp_bits, size_t, Power_Mod::Usage_Hints hints) { static const size_t wsize[][2] = { - { 2048, 7 }, { 1024, 6 }, { 256, 5 }, { 128, 4 }, { 64, 3 }, { 0, 0 } + { 1434, 7 }, + { 539, 6 }, + { 197, 4 }, + { 70, 3 }, + { 25, 2 }, + { 0, 0 } }; size_t window_bits = 1; diff --git a/src/math/numbertheory/powm_mnt.cpp b/src/math/numbertheory/powm_mnt.cpp index 421470364..8993f4ba9 100644 --- a/src/math/numbertheory/powm_mnt.cpp +++ b/src/math/numbertheory/powm_mnt.cpp @@ -33,13 +33,12 @@ void Montgomery_Exponentiator::set_base(const BigInt& base) SecureVector<word> workspace(z.size()); g[0] = (base >= modulus) ? (base % modulus) : base; - bigint_mul(&z[0], z.size(), &workspace[0], - g[0].data(), g[0].size(), g[0].sig_words(), - R2.data(), R2.size(), R2.sig_words()); - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + bigint_monty_mul(&z[0], z.size(), + g[0].data(), g[0].size(), g[0].sig_words(), + R2.data(), R2.size(), R2.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); g[0].assign(&z[0], mod_words + 1); @@ -52,13 +51,11 @@ void Montgomery_Exponentiator::set_base(const BigInt& base) const size_t y_sig = y.sig_words(); zeroise(z); - bigint_mul(&z[0], z.size(), &workspace[0], - x.data(), x.size(), x_sig, - y.data(), y.size(), y_sig); - - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + bigint_monty_mul(&z[0], z.size(), + x.data(), x.size(), x_sig, + y.data(), y.size(), y_sig, + modulus.data(), mod_words, mod_prime, + &workspace[0]); g[i].assign(&z[0], mod_words + 1); } @@ -80,12 +77,11 @@ BigInt Montgomery_Exponentiator::execute() const for(size_t k = 0; k != window_bits; ++k) { zeroise(z); - bigint_sqr(&z[0], z.size(), &workspace[0], - x.data(), x.size(), x.sig_words()); - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + bigint_monty_sqr(&z[0], z.size(), + x.data(), x.size(), x.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); x.assign(&z[0], mod_words + 1); } @@ -95,13 +91,11 @@ BigInt Montgomery_Exponentiator::execute() const const BigInt& y = g[nibble-1]; zeroise(z); - bigint_mul(&z[0], z.size(), &workspace[0], - x.data(), x.size(), x.sig_words(), - y.data(), y.size(), y.sig_words()); - - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + bigint_monty_mul(&z[0], z.size(), + x.data(), x.size(), x.sig_words(), + y.data(), y.size(), y.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); x.assign(&z[0], mod_words + 1); } @@ -110,8 +104,8 @@ BigInt Montgomery_Exponentiator::execute() const x.get_reg().resize(2*mod_words+1); bigint_monty_redc(&x[0], x.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + modulus.data(), mod_words, mod_prime, + &workspace[0]); x.get_reg().resize(mod_words+1); @@ -134,14 +128,12 @@ Montgomery_Exponentiator::Montgomery_Exponentiator(const BigInt& mod, mod_words = modulus.sig_words(); - BigInt mod_prime_bn(BigInt::Power2, MP_WORD_BITS); - mod_prime = (mod_prime_bn - inverse_mod(modulus, mod_prime_bn)).word_at(0); + BigInt r(BigInt::Power2, mod_words * BOTAN_MP_WORD_BITS); + mod_prime = (((r * inverse_mod(r, mod)) - 1) / mod).word_at(0); - R_mod = BigInt(BigInt::Power2, MP_WORD_BITS * mod_words); - R_mod %= modulus; + R_mod = r % modulus; - R2 = BigInt(BigInt::Power2, 2 * MP_WORD_BITS * mod_words); - R2 %= modulus; + R2 = (R_mod * R_mod) % modulus; } } diff --git a/src/math/numbertheory/reducer.cpp b/src/math/numbertheory/reducer.cpp index 257ece56e..466996e99 100644 --- a/src/math/numbertheory/reducer.cpp +++ b/src/math/numbertheory/reducer.cpp @@ -1,6 +1,6 @@ /* * Modular Reducer -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -22,10 +22,8 @@ Modular_Reducer::Modular_Reducer(const BigInt& mod) mod_words = modulus.sig_words(); modulus_2 = Botan::square(modulus); - mod2_words = modulus_2.sig_words(); mu = BigInt(BigInt::Power2, 2 * MP_WORD_BITS * mod_words) / modulus; - mu_words = mu.sig_words(); } /* @@ -36,45 +34,49 @@ BigInt Modular_Reducer::reduce(const BigInt& x) const if(mod_words == 0) throw Invalid_State("Modular_Reducer: Never initalized"); - BigInt t1 = x; - t1.set_sign(BigInt::Positive); - - if(t1 < modulus) + if(x.cmp(modulus, false) < 0) { - if(x.is_negative() && t1.is_nonzero()) - return modulus - t1; + if(x.is_negative()) + return x + modulus; // make positive return x; } + else if(x.cmp(modulus_2, false) < 0) + { + BigInt t1 = x; + t1.set_sign(BigInt::Positive); + t1 >>= (MP_WORD_BITS * (mod_words - 1)); + t1 *= mu; - if(t1 >= modulus_2) - return (x % modulus); + t1 >>= (MP_WORD_BITS * (mod_words + 1)); + t1 *= modulus; - t1 >>= (MP_WORD_BITS * (mod_words - 1)); - t1 *= mu; - t1 >>= (MP_WORD_BITS * (mod_words + 1)); + t1.mask_bits(MP_WORD_BITS * (mod_words + 1)); - t1 *= modulus; - t1.mask_bits(MP_WORD_BITS * (mod_words+1)); + BigInt t2 = x; + t2.set_sign(BigInt::Positive); + t2.mask_bits(MP_WORD_BITS * (mod_words + 1)); - BigInt t2 = x; - t2.set_sign(BigInt::Positive); - t2.mask_bits(MP_WORD_BITS * (mod_words+1)); + t2 -= t1; - t1 = t2 - t1; + if(t2.is_negative()) + { + BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (mod_words + 1)); + t2 += b_to_k1; + } - if(t1.is_negative()) + while(t2 >= modulus) + t2 -= modulus; + + if(x.is_positive()) + return t2; + else + return (modulus - t2); + } + else { - BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (mod_words+1)); - t1 += b_to_k1; + // too big, fall back to normal division + return (x % modulus); } - - while(t1 >= modulus) - t1 -= modulus; - - if(x.is_negative() && t1.is_nonzero()) - t1 = modulus - t1; - - return t1; } } diff --git a/src/math/numbertheory/reducer.h b/src/math/numbertheory/reducer.h index 05c12a440..76712074c 100644 --- a/src/math/numbertheory/reducer.h +++ b/src/math/numbertheory/reducer.h @@ -13,7 +13,7 @@ namespace Botan { /** -* Modular Reducer +* Modular Reducer (using Barrett's technique) */ class BOTAN_DLL Modular_Reducer { @@ -53,7 +53,7 @@ class BOTAN_DLL Modular_Reducer Modular_Reducer(const BigInt& mod); private: BigInt modulus, modulus_2, mu; - size_t mod_words, mod2_words, mu_words; + size_t mod_words; }; } diff --git a/src/passhash/bcrypt/bcrypt.cpp b/src/passhash/bcrypt/bcrypt.cpp index e533c6081..bb2e9095a 100644 --- a/src/passhash/bcrypt/bcrypt.cpp +++ b/src/passhash/bcrypt/bcrypt.cpp @@ -11,11 +11,6 @@ #include <botan/blowfish.h> #include <botan/base64.h> -#include <botan/pipe.h> -#include <botan/b64_filt.h> -#include <iostream> -#include <stdio.h> - namespace Botan { namespace { @@ -89,10 +84,7 @@ MemoryVector<byte> bcrypt_base64_decode(std::string input) for(size_t i = 0; i != input.size(); ++i) input[i] = OPENBSD_BASE64_SUB[static_cast<byte>(input[i])]; - //return base64_decode(input); - Pipe pipe(new Base64_Decoder); - pipe.process_msg(input); - return pipe.read_all(); + return base64_decode(input); } std::string make_bcrypt(const std::string& pass, diff --git a/src/pk_pad/eme1/eme1.cpp b/src/pk_pad/eme1/eme1.cpp index b49fb9af0..1cc0c332d 100644 --- a/src/pk_pad/eme1/eme1.cpp +++ b/src/pk_pad/eme1/eme1.cpp @@ -65,38 +65,47 @@ SecureVector<byte> EME1::unpad(const byte in[], size_t in_length, if(in_length > key_length) in_length = 0; - SecureVector<byte> tmp(key_length); - tmp.copy(key_length - in_length, in, in_length); + SecureVector<byte> input(key_length); + input.copy(key_length - in_length, in, in_length); - mgf->mask(&tmp[Phash.size()], tmp.size() - Phash.size(), - &tmp[0], Phash.size()); - mgf->mask(&tmp[0], Phash.size(), - &tmp[Phash.size()], tmp.size() - Phash.size()); + mgf->mask(&input[Phash.size()], input.size() - Phash.size(), + &input[0], Phash.size()); + mgf->mask(&input[0], Phash.size(), + &input[Phash.size()], input.size() - Phash.size()); - const bool phash_ok = same_mem(&tmp[Phash.size()], &Phash[0], Phash.size()); + bool waiting_for_delim = true; + bool bad_input = false; + size_t delim_idx = 2 * Phash.size(); - bool delim_ok = true; - size_t delim_idx = 0; - - // Is this vulnerable to timing attacks? - for(size_t i = Phash.size() + Phash.size(); i != tmp.size(); ++i) + /* + * GCC 4.5 on x86-64 compiles this in a way that is still vunerable + * to timing analysis. Other compilers, or GCC on other platforms, + * may or may not. + */ + for(size_t i = delim_idx; i != input.size(); ++i) { - if(tmp[i] && !delim_idx) - { - if(tmp[i] == 0x01) - delim_idx = i; - else - delim_ok = false; - } - } + const bool zero_p = !input[i]; + const bool one_p = input[i] == 0x01; - if(delim_idx && delim_ok && phash_ok) - { - return SecureVector<byte>(&tmp[delim_idx + 1], - tmp.size() - delim_idx - 1); + const bool add_1 = waiting_for_delim && zero_p; + + bad_input |= waiting_for_delim && !(zero_p || one_p); + + delim_idx += add_1; + + waiting_for_delim &= zero_p; } - throw Decoding_Error("Invalid EME1 encoding"); + // If we never saw any non-zero byte, then it's not valid input + bad_input |= waiting_for_delim; + + bad_input |= !same_mem(&input[Phash.size()], &Phash[0], Phash.size()); + + if(bad_input) + throw Decoding_Error("Invalid EME1 encoding"); + + return SecureVector<byte>(input + delim_idx + 1, + input.size() - delim_idx - 1); } /* diff --git a/src/pubkey/ec_group/ec_group.h b/src/pubkey/ec_group/ec_group.h index b7b09985e..9430a8e38 100644 --- a/src/pubkey/ec_group/ec_group.h +++ b/src/pubkey/ec_group/ec_group.h @@ -40,9 +40,9 @@ class BOTAN_DLL EC_Group * @param cofactor the cofactor */ EC_Group(const CurveGFp& curve, - const PointGFp& base_point, - const BigInt& order, - const BigInt& cofactor) : + const PointGFp& base_point, + const BigInt& order, + const BigInt& cofactor) : curve(curve), base_point(base_point), order(order), diff --git a/src/pubkey/ec_group/info.txt b/src/pubkey/ec_group/info.txt index c611914e9..9a686feeb 100644 --- a/src/pubkey/ec_group/info.txt +++ b/src/pubkey/ec_group/info.txt @@ -2,8 +2,9 @@ define ECC_GROUP <requires> asn1 -numbertheory -pem +ec_gfp libstate +numbertheory oid_lookup +pem </requires> diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt index be281d697..ceb98a79e 100644 --- a/src/pubkey/ecc_key/info.txt +++ b/src/pubkey/ecc_key/info.txt @@ -4,6 +4,7 @@ define ECC_PUBLIC_KEY_CRYPTO alloc asn1 bigint +ec_gfp ec_group numbertheory </requires> diff --git a/src/pubkey/ecdh/ecdh.h b/src/pubkey/ecdh/ecdh.h index 2edbfe86d..6fe0697bf 100644 --- a/src/pubkey/ecdh/ecdh.h +++ b/src/pubkey/ecdh/ecdh.h @@ -22,7 +22,6 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey { public: - ECDH_PublicKey(const AlgorithmIdentifier& alg_id, const MemoryRegion<byte>& key_bits) : EC_PublicKey(alg_id, key_bits) {} diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 9a3510c33..5c45c5ed3 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -80,12 +80,13 @@ bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len, BigInt r(sig, sig_len / 2); BigInt s(sig + sig_len / 2, sig_len / 2); - if(r < 0 || r >= order || s < 0 || s >= order) + if(r <= 0 || r >= order || s <= 0 || s >= order) return false; BigInt w = inverse_mod(s, order); - PointGFp R = w * (e * base_point + r * public_point); + PointGFp R = w * multi_exponentiate(base_point, e, + public_point, r); if(R.is_zero()) return false; diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp index 507ebb5a0..f97f83aa0 100644 --- a/src/pubkey/gost_3410/gost_3410.cpp +++ b/src/pubkey/gost_3410/gost_3410.cpp @@ -17,8 +17,8 @@ namespace Botan { MemoryVector<byte> GOST_3410_PublicKey::x509_subject_public_key() const { // Trust CryptoPro to come up with something obnoxious - const BigInt& x = public_point().get_affine_x(); - const BigInt& y = public_point().get_affine_y(); + const BigInt x = public_point().get_affine_x(); + const BigInt y = public_point().get_affine_y(); size_t part_size = std::max(x.bytes(), y.bytes()); @@ -153,7 +153,7 @@ bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len, BigInt s(sig, sig_len / 2); BigInt r(sig + sig_len / 2, sig_len / 2); - if(r < 0 || r >= order || s < 0 || s >= order) + if(r <= 0 || r >= order || s <= 0 || s >= order) return false; e %= order; @@ -165,7 +165,11 @@ bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len, BigInt z1 = (s*v) % order; BigInt z2 = (-r*v) % order; - PointGFp R = (z1 * base_point + z2 * public_point); + PointGFp R = multi_exponentiate(base_point, z1, + public_point, z2); + + if(R.is_zero()) + return false; return (R.get_affine_x() == r); } diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp index 4d2837dac..0dac31cef 100644 --- a/src/selftest/selftest.cpp +++ b/src/selftest/selftest.cpp @@ -24,7 +24,7 @@ bool test_filter_kat(Filter* filter, Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder); pipe.process_msg(input); - std::string output = pipe.read_all_as_string(); + const std::string output = pipe.read_all_as_string(); return (output == expected_output); } diff --git a/src/utils/simd_32/info.txt b/src/simd/info.txt index 362e90235..d0601b141 100644 --- a/src/utils/simd_32/info.txt +++ b/src/simd/info.txt @@ -2,7 +2,8 @@ define SIMD_32 <header:internal> simd_32.h -simd_sse.h -simd_scalar.h -simd_altivec.h </header:internal> + +<requires> +simd_sse2|simd_altivec|simd_scalar +</requires> diff --git a/src/utils/simd_32/simd_32.h b/src/simd/simd_32.h index e172fa919..4ef0cea85 100644 --- a/src/utils/simd_32/simd_32.h +++ b/src/simd/simd_32.h @@ -1,6 +1,6 @@ /* * Lightweight wrappers for SIMD operations -* (C) 2009 Jack Lloyd +* (C) 2009,2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -9,23 +9,22 @@ #define BOTAN_SIMD_32_H__ #include <botan/types.h> -#include <botan/rotate.h> -#if defined(BOTAN_TARGET_CPU_HAS_SSE2) && !defined(BOTAN_NO_SSE_INTRINSICS) - - #include <botan/internal/simd_sse.h> +#if defined(BOTAN_HAS_SIMD_SSE2) + #include <botan/internal/simd_sse2.h> namespace Botan { typedef SIMD_SSE2 SIMD_32; } -#elif defined(BOTAN_TARGET_CPU_HAS_ALTIVEC) - +#elif defined(BOTAN_HAS_SIMD_ALTIVEC) #include <botan/internal/simd_altivec.h> namespace Botan { typedef SIMD_Altivec SIMD_32; } -#else - +#elif defined(BOTAN_HAS_SIMD_SCALAR) #include <botan/internal/simd_scalar.h> namespace Botan { typedef SIMD_Scalar SIMD_32; } +#else + #error "No SIMD module defined" + #endif #endif diff --git a/src/simd/simd_altivec/info.txt b/src/simd/simd_altivec/info.txt new file mode 100644 index 000000000..aa2f01c2d --- /dev/null +++ b/src/simd/simd_altivec/info.txt @@ -0,0 +1,9 @@ +define SIMD_ALTIVEC + +need_isa altivec + +load_on dep + +<header:internal> +simd_altivec.h +</header:internal> diff --git a/src/utils/simd_32/simd_altivec.h b/src/simd/simd_altivec/simd_altivec.h index 4c412ddec..4c412ddec 100644 --- a/src/utils/simd_32/simd_altivec.h +++ b/src/simd/simd_altivec/simd_altivec.h diff --git a/src/simd/simd_scalar/info.txt b/src/simd/simd_scalar/info.txt new file mode 100644 index 000000000..6817eab80 --- /dev/null +++ b/src/simd/simd_scalar/info.txt @@ -0,0 +1,7 @@ +define SIMD_SCALAR + +load_on dep + +<header:internal> +simd_scalar.h +</header:internal> diff --git a/src/utils/simd_32/simd_scalar.h b/src/simd/simd_scalar/simd_scalar.h index 2c68622af..2c68622af 100644 --- a/src/utils/simd_32/simd_scalar.h +++ b/src/simd/simd_scalar/simd_scalar.h diff --git a/src/simd/simd_sse2/info.txt b/src/simd/simd_sse2/info.txt new file mode 100644 index 000000000..e56792491 --- /dev/null +++ b/src/simd/simd_sse2/info.txt @@ -0,0 +1,9 @@ +define SIMD_SSE2 + +need_isa sse2 + +load_on dep + +<header:internal> +simd_sse2.h +</header:internal> diff --git a/src/utils/simd_32/simd_sse.h b/src/simd/simd_sse2/simd_sse2.h index 61fce99a9..61fce99a9 100644 --- a/src/utils/simd_32/simd_sse.h +++ b/src/simd/simd_sse2/simd_sse2.h diff --git a/src/ssl/hello.cpp b/src/ssl/hello.cpp index 2c5a9d2ea..ae0d9607b 100644 --- a/src/ssl/hello.cpp +++ b/src/ssl/hello.cpp @@ -190,6 +190,14 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf) } } } + else if(extension_code == TLSEXT_SRP_IDENTIFIER) + { + std::vector<byte> name = reader.get_range_vector<byte>(1, 1, 255); + + requested_srp_id.assign( + reinterpret_cast<char*>(&name[0]), + name.size()); + } else { reader.discard_next(extension_size); diff --git a/src/ssl/info.txt b/src/ssl/info.txt index 586a6cec7..169b76115 100644 --- a/src/ssl/info.txt +++ b/src/ssl/info.txt @@ -1,8 +1,12 @@ define SSL_TLS +load_on request + <comment> -The SSL/TLS code is complex, new, and not yet reviewed, there may be -serious bugs or security issues. +A new TLS API is being developed. This version has numerous +performance and usability issues and will not be supported in the +future. Only use it if you need it for compatability with code written +against previous versions. </comment> uses_tr1 yes @@ -57,11 +61,11 @@ emsa3 filters hmac md5 +prf_ssl3 +prf_tls rng rsa sha1 ssl3mac -ssl_prf -tls_prf x509cert </requires> diff --git a/src/ssl/rec_read.cpp b/src/ssl/rec_read.cpp index 042aae0c9..7e295f8a4 100644 --- a/src/ssl/rec_read.cpp +++ b/src/ssl/rec_read.cpp @@ -213,9 +213,14 @@ size_t Record_Reader::get_record(byte& msg_type, } else { + bool padding_good = true; + for(size_t i = 0; i != pad_size; ++i) if(plaintext[plaintext.size()-i-1] != pad_value) - pad_size = 0; + padding_good = false; + + if(!padding_good) + pad_size = 0; } } @@ -223,7 +228,7 @@ size_t Record_Reader::get_record(byte& msg_type, throw Decoding_Error("Record_Reader: Record truncated"); const size_t mac_offset = plaintext.size() - (mac_size + pad_size); - SecureVector<byte> recieved_mac(&plaintext[mac_offset], + SecureVector<byte> received_mac(&plaintext[mac_offset], mac_size); const u16bit plain_length = plaintext.size() - (mac_size + pad_size + iv_size); @@ -242,7 +247,7 @@ size_t Record_Reader::get_record(byte& msg_type, SecureVector<byte> computed_mac = mac->final(); - if(recieved_mac != computed_mac) + if(received_mac != computed_mac) throw TLS_Exception(BAD_RECORD_MAC, "Record_Reader: MAC failure"); msg_type = header[0]; diff --git a/src/ssl/tls_alerts.h b/src/ssl/tls_alerts.h index f189cf507..241599aa8 100644 --- a/src/ssl/tls_alerts.h +++ b/src/ssl/tls_alerts.h @@ -15,7 +15,7 @@ namespace Botan { /** * SSL/TLS Alert Message */ -class BOTAN_DLL Alert +class Alert { public: /** diff --git a/src/ssl/tls_client.cpp b/src/ssl/tls_client.cpp index 5447e9904..a136752fd 100644 --- a/src/ssl/tls_client.cpp +++ b/src/ssl/tls_client.cpp @@ -294,7 +294,7 @@ void TLS_Client::state_machine() } } else - throw Unexpected_Message("Unknown message type recieved"); + throw Unexpected_Message("Unknown message type received"); } /** @@ -440,7 +440,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, is_rsa = true; else throw TLS_Exception(UNSUPPORTED_CERTIFICATE, - "Unknown key type recieved in server kex"); + "Unknown key type received in server kex"); if((is_dsa && state->suite.sig_type() != TLS_ALGO_SIGNER_DSA) || (is_rsa && state->suite.sig_type() != TLS_ALGO_SIGNER_RSA)) @@ -469,7 +469,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, is_rsa = true; else throw TLS_Exception(HANDSHAKE_FAILURE, - "Unknown key type recieved in server kex"); + "Unknown key type received in server kex"); if((is_dh && state->suite.kex_type() != TLS_ALGO_KEYEXCH_DH) || (is_rsa && state->suite.kex_type() != TLS_ALGO_KEYEXCH_RSA)) @@ -560,7 +560,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, active = true; } else - throw Unexpected_Message("Unknown handshake message recieved"); + throw Unexpected_Message("Unknown handshake message received"); } /** diff --git a/src/ssl/tls_exceptn.h b/src/ssl/tls_exceptn.h index a9efc718a..37b9c0d27 100644 --- a/src/ssl/tls_exceptn.h +++ b/src/ssl/tls_exceptn.h @@ -32,7 +32,7 @@ class BOTAN_DLL TLS_Exception : public Exception /** * Unexpected_Message Exception */ -struct Unexpected_Message : public TLS_Exception +struct BOTAN_DLL Unexpected_Message : public TLS_Exception { Unexpected_Message(const std::string& err) : TLS_Exception(UNEXPECTED_MESSAGE, err) {} diff --git a/src/ssl/tls_handshake_hash.h b/src/ssl/tls_handshake_hash.h index ceaa55584..cea612a71 100644 --- a/src/ssl/tls_handshake_hash.h +++ b/src/ssl/tls_handshake_hash.h @@ -17,7 +17,7 @@ using namespace Botan; /** * TLS Handshake Hash */ -class BOTAN_DLL HandshakeHash +class HandshakeHash { public: void update(const byte in[], size_t length) diff --git a/src/ssl/tls_magic.h b/src/ssl/tls_magic.h index 0c2a610b1..00898738e 100644 --- a/src/ssl/tls_magic.h +++ b/src/ssl/tls_magic.h @@ -181,6 +181,8 @@ enum TLS_Handshake_Extension_Type { TLSEXT_USABLE_ELLIPTIC_CURVES = 10, TLSEXT_EC_POINT_FORMATS = 11, + TLSEXT_SRP_IDENTIFIER = 12, + TLSEXT_CERTIFICATE_TYPES = 9, TLSEXT_SESSION_TICKET = 35 }; diff --git a/src/ssl/tls_messages.h b/src/ssl/tls_messages.h index c5d4d8cb8..e7eaa56e1 100644 --- a/src/ssl/tls_messages.h +++ b/src/ssl/tls_messages.h @@ -21,7 +21,7 @@ namespace Botan { /** * TLS Handshake Message Base Class */ -class BOTAN_DLL HandshakeMessage +class HandshakeMessage { public: void send(Record_Writer&, HandshakeHash&) const; @@ -38,7 +38,7 @@ class BOTAN_DLL HandshakeMessage /** * Client Hello Message */ -class BOTAN_DLL Client_Hello : public HandshakeMessage +class Client_Hello : public HandshakeMessage { public: Handshake_Type type() const { return CLIENT_HELLO; } @@ -51,6 +51,8 @@ class BOTAN_DLL Client_Hello : public HandshakeMessage std::string hostname() const { return requested_hostname; } + std::string srp_identifier() const { return requested_srp_id; } + bool offered_suite(u16bit) const; Client_Hello(RandomNumberGenerator& rng, @@ -75,12 +77,13 @@ class BOTAN_DLL Client_Hello : public HandshakeMessage std::vector<u16bit> suites; std::vector<byte> comp_algos; std::string requested_hostname; + std::string requested_srp_id; }; /** * Client Key Exchange Message */ -class BOTAN_DLL Client_Key_Exchange : public HandshakeMessage +class Client_Key_Exchange : public HandshakeMessage { public: Handshake_Type type() const { return CLIENT_KEX; } @@ -112,7 +115,7 @@ class BOTAN_DLL Client_Key_Exchange : public HandshakeMessage /** * Certificate Message */ -class BOTAN_DLL Certificate : public HandshakeMessage +class Certificate : public HandshakeMessage { public: Handshake_Type type() const { return CERTIFICATE; } @@ -130,7 +133,7 @@ class BOTAN_DLL Certificate : public HandshakeMessage /** * Certificate Request Message */ -class BOTAN_DLL Certificate_Req : public HandshakeMessage +class Certificate_Req : public HandshakeMessage { public: Handshake_Type type() const { return CERTIFICATE_REQUEST; } @@ -157,7 +160,7 @@ class BOTAN_DLL Certificate_Req : public HandshakeMessage /** * Certificate Verify Message */ -class BOTAN_DLL Certificate_Verify : public HandshakeMessage +class Certificate_Verify : public HandshakeMessage { public: Handshake_Type type() const { return CERTIFICATE_VERIFY; } @@ -179,7 +182,7 @@ class BOTAN_DLL Certificate_Verify : public HandshakeMessage /** * Finished Message */ -class BOTAN_DLL Finished : public HandshakeMessage +class Finished : public HandshakeMessage { public: Handshake_Type type() const { return FINISHED; } @@ -205,7 +208,7 @@ class BOTAN_DLL Finished : public HandshakeMessage /** * Hello Request Message */ -class BOTAN_DLL Hello_Request : public HandshakeMessage +class Hello_Request : public HandshakeMessage { public: Handshake_Type type() const { return HELLO_REQUEST; } @@ -220,7 +223,7 @@ class BOTAN_DLL Hello_Request : public HandshakeMessage /** * Server Hello Message */ -class BOTAN_DLL Server_Hello : public HandshakeMessage +class Server_Hello : public HandshakeMessage { public: Handshake_Type type() const { return SERVER_HELLO; } @@ -250,7 +253,7 @@ class BOTAN_DLL Server_Hello : public HandshakeMessage /** * Server Key Exchange Message */ -class BOTAN_DLL Server_Key_Exchange : public HandshakeMessage +class Server_Key_Exchange : public HandshakeMessage { public: Handshake_Type type() const { return SERVER_KEX; } @@ -277,7 +280,7 @@ class BOTAN_DLL Server_Key_Exchange : public HandshakeMessage /** * Server Hello Done Message */ -class BOTAN_DLL Server_Hello_Done : public HandshakeMessage +class Server_Hello_Done : public HandshakeMessage { public: Handshake_Type type() const { return SERVER_HELLO_DONE; } diff --git a/src/ssl/tls_record.h b/src/ssl/tls_record.h index 7a223095f..09fd921c6 100644 --- a/src/ssl/tls_record.h +++ b/src/ssl/tls_record.h @@ -16,7 +16,13 @@ #include <vector> #if defined(BOTAN_USE_STD_TR1) - #include <tr1/functional> + +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) + #include <functional> +#else + #include <tr1/functional> +#endif + #elif defined(BOTAN_USE_BOOST_TR1) #include <boost/tr1/functional.hpp> #else diff --git a/src/ssl/tls_server.cpp b/src/ssl/tls_server.cpp index 4e071da59..8964be3d7 100644 --- a/src/ssl/tls_server.cpp +++ b/src/ssl/tls_server.cpp @@ -262,7 +262,7 @@ void TLS_Server::state_machine() } } else - throw Unexpected_Message("Unknown message type recieved"); + throw Unexpected_Message("Unknown message type received"); } /* @@ -471,7 +471,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, active = true; } else - throw Unexpected_Message("Unknown handshake message recieved"); + throw Unexpected_Message("Unknown handshake message received"); } /* diff --git a/src/utils/asm_x86_32/info.txt b/src/utils/asm_x86_32/info.txt index 8534d9aef..21244968f 100644 --- a/src/utils/asm_x86_32/info.txt +++ b/src/utils/asm_x86_32/info.txt @@ -19,7 +19,6 @@ solaris </os> <cc> -clang gcc icc </cc> diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index cb6fdaba5..f6581f09c 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -10,10 +10,20 @@ #include <botan/get_byte.h> #include <botan/mem_ops.h> +#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) + #if defined(BOTAN_TARGET_OS_IS_DARWIN) #include <sys/sysctl.h> #endif +#if defined(BOTAN_TARGET_OS_IS_OPENBSD) + #include <sys/param.h> + #include <sys/sysctl.h> + #include <machine/cpu.h> +#endif + +#endif + #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) @@ -24,9 +34,9 @@ #elif defined(BOTAN_BUILD_COMPILER_IS_INTEL) #include <ia32intrin.h> - #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0); + #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0) -#elif (BOTAN_GCC_VERSION >= 430) +#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 430) // Only available starting in GCC 4.3 #include <cpuid.h> @@ -46,6 +56,20 @@ namespace { } +#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && \ + (defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_GCC)) + + /* + * We can't safely use this on x86-32 as some 32-bit ABIs use ebx as + * a PIC register, and in theory there are some x86-32s still out + * there that don't support cpuid at all; it requires strange + * contortions to detect them. + */ + + #define CALL_CPUID(type, out) \ + asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \ + : "0" (type)) + #else #warning "No method of calling CPUID for this compiler" #endif @@ -92,10 +116,14 @@ u32bit get_x86_cache_line_size() bool altivec_check_sysctl() { -#if defined(BOTAN_TARGET_OS_IS_DARWIN) +#if defined(BOTAN_TARGET_OS_IS_DARWIN) || defined(BOTAN_TARGET_OS_IS_OPENBSD) +#if defined(BOTAN_TARGET_OS_IS_OPENBSD) + int sels[2] = { CTL_MACHDEP, CPU_ALTIVEC }; +#else // From Apple's docs int sels[2] = { CTL_HW, HW_VECTORUNIT }; +#endif int vector_type = 0; size_t length = sizeof(vector_type); int error = sysctl(sels, 2, &vector_type, &length, NULL, 0); @@ -128,6 +156,7 @@ bool altivec_check_pvr_emul() const u16bit PVR_G5_970MP = 0x0044; const u16bit PVR_G5_970GX = 0x0045; const u16bit PVR_POWER6 = 0x003E; + const u16bit PVR_POWER7 = 0x003F; const u16bit PVR_CELL_PPU = 0x0070; // Motorola produced G4s with PVR 0x800[0123C] (at least) @@ -147,6 +176,7 @@ bool altivec_check_pvr_emul() altivec_capable |= (pvr == PVR_G5_970MP); altivec_capable |= (pvr == PVR_G5_970GX); altivec_capable |= (pvr == PVR_POWER6); + altivec_capable |= (pvr == PVR_POWER7); altivec_capable |= (pvr == PVR_CELL_PPU); #endif diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h index 863ba5b63..ad85ac4fe 100644 --- a/src/utils/cpuid.h +++ b/src/utils/cpuid.h @@ -83,6 +83,12 @@ class BOTAN_DLL CPUID { return x86_processor_flags_has(CPUID_MOVBE_BIT); } /** + * Check if the processor supports RDRAND + */ + static bool has_rdrand() + { return x86_processor_flags_has(CPUID_RDRAND_BIT); } + + /** * Check if the processor supports AltiVec/VMX */ static bool has_altivec() { return altivec_capable; } @@ -96,7 +102,8 @@ class BOTAN_DLL CPUID CPUID_SSE42_BIT = 52, CPUID_MOVBE_BIT = 54, CPUID_AESNI_BIT = 57, - CPUID_AVX_BIT = 60 + CPUID_AVX_BIT = 60, + CPUID_RDRAND_BIT = 61 }; static bool x86_processor_flags_has(u64bit bit) diff --git a/src/utils/dyn_load/dyn_load.cpp b/src/utils/dyn_load/dyn_load.cpp index 4a8cb16fa..06b8c5df3 100644 --- a/src/utils/dyn_load/dyn_load.cpp +++ b/src/utils/dyn_load/dyn_load.cpp @@ -39,7 +39,7 @@ Dynamically_Loaded_Library::Dynamically_Loaded_Library( raise_runtime_loader_exception(lib_name, dlerror()); #elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) - lib = ::LoadLibrary(lib_name.c_str()); + lib = ::LoadLibraryA(lib_name.c_str()); if(!lib) raise_runtime_loader_exception(lib_name, "LoadLibrary failed"); @@ -65,7 +65,8 @@ void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol) #if defined(BOTAN_TARGET_OS_HAS_DLOPEN) addr = ::dlsym(lib, symbol.c_str()); #elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY) - addr = ::GetProcAddress((HMODULE)lib, symbol.c_str()); + addr = reinterpret_cast<void*>(::GetProcAddress((HMODULE)lib, + symbol.c_str())); #endif if(!addr) diff --git a/src/utils/exceptn.h b/src/utils/exceptn.h index 1177a4e7d..3797a5478 100644 --- a/src/utils/exceptn.h +++ b/src/utils/exceptn.h @@ -146,8 +146,8 @@ struct BOTAN_DLL Decoding_Error : public Invalid_Argument */ struct BOTAN_DLL Integrity_Failure : public Exception { - Integrity_Failure(const std::string& what) : - Exception("Integrity failure: " + what) {} + Integrity_Failure(const std::string& msg) : + Exception("Integrity failure: " + msg) {} }; /** diff --git a/src/utils/version.cpp b/src/utils/version.cpp index cf3205d19..acc8bee61 100644 --- a/src/utils/version.cpp +++ b/src/utils/version.cpp @@ -33,6 +33,7 @@ std::string version_string() else out << "released " << version_datestamp(); + out << ", revision " << BOTAN_VERSION_VC_REVISION; out << ", distribution " << BOTAN_DISTRIBUTION_INFO << ")"; return out.str(); diff --git a/src/wrap/python/filter.cpp b/src/wrap/python/filter.cpp index 437c5239f..e329ed708 100644 --- a/src/wrap/python/filter.cpp +++ b/src/wrap/python/filter.cpp @@ -26,7 +26,6 @@ class Py_Filter : public Filter void send_str(const std::string& str) { - printf("Py_Filter::send_str\n"); send((const byte*)str.data(), str.length()); } }; @@ -36,14 +35,12 @@ class FilterWrapper : public Py_Filter, public wrapper<Py_Filter> public: void start_msg() { - printf("wrapper start_msg\n"); if(override start_msg = this->get_override("start_msg")) start_msg(); } void end_msg() { - printf("wrapper end_msg\n"); if(override end_msg = this->get_override("end_msg")) end_msg(); } @@ -53,7 +50,6 @@ class FilterWrapper : public Py_Filter, public wrapper<Py_Filter> virtual void write_str(const std::string& str) { - printf("wrapper write\n"); this->get_override("write")(str); } }; @@ -125,7 +121,6 @@ void prepend_filter(Pipe& pipe, std::auto_ptr<Filter> filter) void do_send(std::auto_ptr<FilterWrapper> filter, const std::string& data) { - printf("Sending %s to %p\n", data.c_str(), filter.get()); filter->send_str(data); } diff --git a/src/wrap/python/rsa.cpp b/src/wrap/python/rsa.cpp index 5e2e0ba30..dc6053503 100644 --- a/src/wrap/python/rsa.cpp +++ b/src/wrap/python/rsa.cpp @@ -27,6 +27,8 @@ class Py_RSA_PrivateKey Py_RSA_PrivateKey(std::string pem_str, Python_RandomNumberGenerator& rng, std::string pass); + Py_RSA_PrivateKey(std::string pem_str, + Python_RandomNumberGenerator& rng); Py_RSA_PrivateKey(u32bit bits, Python_RandomNumberGenerator& rng); ~Py_RSA_PrivateKey() { delete rsa_key; } @@ -87,6 +89,21 @@ Py_RSA_PrivateKey::Py_RSA_PrivateKey(u32bit bits, } Py_RSA_PrivateKey::Py_RSA_PrivateKey(std::string pem_str, + Python_RandomNumberGenerator& rng) + { + DataSource_Memory in(pem_str); + + Private_Key* pkcs8_key = + PKCS8::load_key(in, + rng.get_underlying_rng()); + + rsa_key = dynamic_cast<RSA_PrivateKey*>(pkcs8_key); + + if(!rsa_key) + throw std::invalid_argument("Key is not an RSA key"); + } + +Py_RSA_PrivateKey::Py_RSA_PrivateKey(std::string pem_str, Python_RandomNumberGenerator& rng, std::string passphrase) { @@ -195,6 +212,7 @@ void export_rsa() python::class_<Py_RSA_PrivateKey> ("RSA_PrivateKey", python::init<std::string, Python_RandomNumberGenerator&, std::string>()) + .def(python::init<std::string, Python_RandomNumberGenerator&>()) .def(python::init<u32bit, Python_RandomNumberGenerator&>()) .def("to_string", &Py_RSA_PrivateKey::to_string) .def("to_ber", &Py_RSA_PrivateKey::to_ber) |