aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Attic/mutex/pthreads/info.txt3
-rw-r--r--checks/algos.cpp2
-rw-r--r--checks/bench.cpp56
-rw-r--r--checks/bench.h4
-rw-r--r--checks/check.cpp25
-rw-r--r--checks/pk_bench.cpp4
-rw-r--r--checks/validate.dat1090
-rwxr-xr-xconfigure.py100
-rw-r--r--doc/api.tex180
-rw-r--r--doc/credits.txt5
-rw-r--r--doc/examples/bench.cpp98
-rw-r--r--doc/examples/cryptobox.cpp50
-rw-r--r--doc/examples/gen_certs.cpp124
-rw-r--r--doc/license.txt27
-rw-r--r--doc/log.txt24
-rwxr-xr-xdoc/scripts/configure.pl (renamed from configure.pl)59
-rwxr-xr-xdoc/scripts/dist.sh6
-rw-r--r--readme.txt2
-rw-r--r--src/algo_factory/algo_factory.cpp4
-rw-r--r--src/alloc/alloc_mmap/info.txt1
-rw-r--r--src/aont/info.txt17
-rw-r--r--src/aont/package.cpp128
-rw-r--r--src/aont/package.h45
-rw-r--r--src/benchmark/benchmark.cpp5
-rw-r--r--src/block/aes/aes.cpp266
-rw-r--r--src/block/aes/aes.h8
-rw-r--r--src/block/block_cipher.h20
-rw-r--r--src/block/blowfish/blowfish.cpp70
-rw-r--r--src/block/blowfish/blowfish.h8
-rw-r--r--src/block/cast/cast128.cpp100
-rw-r--r--src/block/cast/cast128.h6
-rw-r--r--src/block/cast/cast256.cpp140
-rw-r--r--src/block/cast/cast256.h6
-rw-r--r--src/block/des/des.cpp144
-rw-r--r--src/block/des/des.h12
-rw-r--r--src/block/des/desx.cpp28
-rw-r--r--src/block/des/desx.h6
-rw-r--r--src/block/gost_28147/gost_28147.cpp67
-rw-r--r--src/block/gost_28147/gost_28147.h5
-rw-r--r--src/block/idea/idea.cpp132
-rw-r--r--src/block/idea/idea.h6
-rw-r--r--src/block/kasumi/kasumi.cpp110
-rw-r--r--src/block/kasumi/kasumi.h5
-rw-r--r--src/block/lion/lion.cpp52
-rw-r--r--src/block/lion/lion.h5
-rw-r--r--src/block/lubyrack/lubyrack.cpp104
-rw-r--r--src/block/lubyrack/lubyrack.h6
-rw-r--r--src/block/mars/mars.cpp138
-rw-r--r--src/block/mars/mars.h6
-rw-r--r--src/block/misty1/misty1.cpp130
-rw-r--r--src/block/misty1/misty1.h6
-rw-r--r--src/block/noekeon/noekeon.cpp92
-rw-r--r--src/block/noekeon/noekeon.h6
-rw-r--r--src/block/rc2/rc2.cpp104
-rw-r--r--src/block/rc2/rc2.h6
-rw-r--r--src/block/rc5/rc5.cpp72
-rw-r--r--src/block/rc5/rc5.h6
-rw-r--r--src/block/rc6/rc6.cpp140
-rw-r--r--src/block/rc6/rc6.h6
-rw-r--r--src/block/safer/safer_sk.cpp97
-rw-r--r--src/block/safer/safer_sk.h7
-rw-r--r--src/block/seed/seed.cpp116
-rw-r--r--src/block/seed/seed.h6
-rw-r--r--src/block/serpent/serpent.cpp172
-rw-r--r--src/block/serpent/serpent.h5
-rw-r--r--src/block/serpent_ia32/info.txt1
-rw-r--r--src/block/serpent_ia32/serp_ia32.cpp18
-rw-r--r--src/block/serpent_ia32/serp_ia32.h5
-rw-r--r--src/block/serpent_ia32/serp_ia32_imp.S28
-rw-r--r--src/block/serpent_sse2/info.txt16
-rw-r--r--src/block/serpent_sse2/serp_sse2.cpp240
-rw-r--r--src/block/serpent_sse2/serp_sse2.h29
-rw-r--r--src/block/serpent_sse2/serp_sse2_sbox.h434
-rw-r--r--src/block/skipjack/skipjack.cpp68
-rw-r--r--src/block/skipjack/skipjack.h7
-rw-r--r--src/block/square/square.cpp192
-rw-r--r--src/block/square/square.h6
-rw-r--r--src/block/tea/tea.cpp52
-rw-r--r--src/block/tea/tea.h6
-rw-r--r--src/block/twofish/twofish.cpp156
-rw-r--r--src/block/twofish/twofish.h6
-rw-r--r--src/block/xtea/xtea.cpp45
-rw-r--r--src/block/xtea/xtea.h6
-rw-r--r--src/build-data/arch/arm1
-rw-r--r--src/build-data/arch/m68k5
-rw-r--r--src/build-data/arch/mips3217
-rw-r--r--src/build-data/arch/mips6436
-rw-r--r--src/build-data/arch/ppc1
-rw-r--r--src/build-data/arch/s3903
-rw-r--r--src/build-data/arch/s390x3
-rw-r--r--src/build-data/botan.doxy.in2
-rw-r--r--src/build-data/buildh.in6
-rw-r--r--src/build-data/cc/gcc2
-rw-r--r--src/build-data/cc/open6430
-rw-r--r--src/build-data/os/dragonfly11
-rw-r--r--src/cert/cvc/cvc_cert.cpp2
-rw-r--r--src/cert/cvc/cvc_req.cpp2
-rw-r--r--src/cert/cvc/cvc_self.cpp4
-rw-r--r--src/codec/openpgp/openpgp.cpp1
-rw-r--r--src/cryptobox/cryptobox.cpp146
-rw-r--r--src/cryptobox/cryptobox.h42
-rw-r--r--src/cryptobox/info.txt22
-rw-r--r--src/engine/openssl/ossl_md.cpp10
-rw-r--r--src/engine/sse2_eng/eng_sse2.cpp23
-rw-r--r--src/engine/sse2_eng/eng_sse2.h5
-rw-r--r--src/engine/sse2_eng/info.txt9
-rw-r--r--src/entropy/dev_random/info.txt1
-rw-r--r--src/entropy/egd/es_egd.cpp2
-rw-r--r--src/entropy/egd/info.txt1
-rw-r--r--src/entropy/proc_walk/es_ftw.cpp4
-rw-r--r--src/entropy/proc_walk/info.txt1
-rw-r--r--src/filters/algo_filt.cpp10
-rw-r--r--src/filters/basefilt.cpp21
-rw-r--r--src/filters/basefilt.h33
-rw-r--r--src/filters/fd_unix/info.txt1
-rw-r--r--src/filters/filters.h42
-rw-r--r--src/filters/info.txt1
-rw-r--r--src/filters/key_filt.h45
-rw-r--r--src/hash/md4_ia32/info.txt1
-rw-r--r--src/hash/md4_ia32/md4_ia32_imp.S10
-rw-r--r--src/hash/md5_ia32/info.txt1
-rw-r--r--src/hash/md5_ia32/md5_ia32_imp.S10
-rw-r--r--src/hash/sha1_amd64/sha1_amd64_imp.S10
-rw-r--r--src/hash/sha1_ia32/info.txt1
-rw-r--r--src/hash/sha1_ia32/sha1_ia32_imp.S10
-rw-r--r--src/hash/sha1_sse2/info.txt12
-rw-r--r--src/libstate/info.txt2
-rw-r--r--src/libstate/pk_engine.h1
-rw-r--r--src/libstate/scan_name.cpp4
-rw-r--r--src/libstate/scan_name.h4
-rw-r--r--src/mac/mac.cpp4
-rw-r--r--src/math/bigint/monty_amd64/info.txt1
-rw-r--r--src/math/bigint/monty_amd64/mp_monty.S10
-rw-r--r--src/math/bigint/mp_asm64/mp_asm.h2
-rw-r--r--src/math/bigint/mulop_amd64/info.txt1
-rw-r--r--src/math/bigint/mulop_amd64/mp_mulop_amd64.S10
-rw-r--r--src/math/bigint/mulop_ia32/info.txt1
-rw-r--r--src/math/bigint/mulop_ia32/mp_mulop.S10
-rw-r--r--src/modes/ctr/ctr.cpp111
-rw-r--r--src/modes/ctr/ctr.h21
-rw-r--r--src/modes/eax/eax.h2
-rw-r--r--src/modes/ecb/ecb.cpp191
-rw-r--r--src/modes/ecb/ecb.h68
-rw-r--r--src/modes/modebase.cpp2
-rw-r--r--src/modes/modebase.h9
-rw-r--r--src/modes/xts/xts.cpp8
-rw-r--r--src/modes/xts/xts.h8
-rw-r--r--src/pubkey/dsa/dsa_core.cpp6
-rw-r--r--src/pubkey/ecc_key/ecc_key.cpp2
-rw-r--r--src/pubkey/eckaeg/eckaeg.cpp5
-rw-r--r--src/pubkey/pk_codecs/pkcs8.h7
-rw-r--r--src/rng/auto_rng/auto_rng.cpp2
-rw-r--r--src/selftest/selftest.cpp2
-rw-r--r--src/stream/turing/turing.cpp48
-rw-r--r--src/stream/turing/turing.h2
-rw-r--r--src/timer/gettimeofday/info.txt1
-rw-r--r--src/timer/posix_rt/info.txt1
-rw-r--r--src/utils/bswap.h4
-rw-r--r--src/utils/info.txt2
159 files changed, 5112 insertions, 1835 deletions
diff --git a/Attic/mutex/pthreads/info.txt b/Attic/mutex/pthreads/info.txt
index 88de70de0..f135dea48 100644
--- a/Attic/mutex/pthreads/info.txt
+++ b/Attic/mutex/pthreads/info.txt
@@ -10,7 +10,7 @@ mux_pthr.h
</add>
<libs>
-all!qnx,freebsd,openbsd,netbsd -> pthread
+all!qnx,freebsd,dragonfly,openbsd,netbsd -> pthread
</libs>
<os>
@@ -18,6 +18,7 @@ aix
cygwin
darwin
freebsd
+dragonfly
hpux
irix
linux
diff --git a/checks/algos.cpp b/checks/algos.cpp
index 2edaaf14c..dff903e21 100644
--- a/checks/algos.cpp
+++ b/checks/algos.cpp
@@ -62,6 +62,8 @@ std::vector<algorithm> get_algos()
"AES-128/CTR-BE", 16, 16));
algos.push_back(algorithm("Cipher Mode", "AES-128/EAX", 16, 16));
algos.push_back(algorithm("Cipher Mode", "AES-128/XTS", 32, 16));
+ algos.push_back(algorithm("Cipher Mode", "Serpent/CTR",
+ "Serpent/CTR-BE", 32, 16));
algos.push_back(algorithm("Stream Cipher", "ARC4", 16));
algos.push_back(algorithm("Stream Cipher", "Salsa20", 32));
diff --git a/checks/bench.cpp b/checks/bench.cpp
index 6df7319c0..1610bed1e 100644
--- a/checks/bench.cpp
+++ b/checks/bench.cpp
@@ -27,7 +27,7 @@ namespace {
double bench_filter(std::string name, Botan::Filter* filter,
Botan::RandomNumberGenerator& rng,
- bool html, double seconds)
+ double seconds)
{
Botan::Pipe pipe(filter, new BitBucket);
@@ -52,27 +52,13 @@ double bench_filter(std::string name, Botan::Filter* filter,
std::cout.setf(std::ios::fixed, std::ios::floatfield);
std::cout.precision(2);
- if(html)
- {
- if(name.find("<") != std::string::npos)
- name.replace(name.find("<"), 1, "&lt;");
- if(name.find(">") != std::string::npos)
- name.replace(name.find(">"), 1, "&gt;");
- std::cout << " <TR><TH>" << name
- << std::string(25 - name.length(), ' ') << " <TH>";
- std::cout.width(6);
- std::cout << mbytes_per_sec << std::endl;
- }
- else
- {
- std::cout << name << ": " << std::string(25 - name.length(), ' ');
- std::cout.width(6);
- std::cout << mbytes_per_sec << " MiB/sec" << std::endl;
- }
+ std::cout << name << " " << std::string(25 - name.length(), ' ');
+ std::cout.width(6);
+ std::cout << mbytes_per_sec << " MiB/sec" << std::endl;
return (mbytes_per_sec);
}
-double bench(const std::string& name, const std::string& filtername, bool html,
+double bench(const std::string& name, const std::string& filtername,
double seconds, u32bit keylen, u32bit ivlen,
Botan::RandomNumberGenerator& rng)
{
@@ -88,7 +74,7 @@ double bench(const std::string& name, const std::string& filtername, bool html,
Botan::Filter* filter = lookup(filtername, params);
if(filter)
- return bench_filter(name, filter, rng, html, seconds);
+ return bench_filter(name, filter, rng, seconds);
return 0;
}
@@ -96,23 +82,9 @@ double bench(const std::string& name, const std::string& filtername, bool html,
void benchmark(const std::string& what,
Botan::RandomNumberGenerator& rng,
- bool html, double seconds)
+ double seconds)
{
try {
- if(html)
- {
- std::cout << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD "
- << "HTML 4.0 Transitional//EN\">\n"
- << "<HTML>\n\n"
- << "<TITLE>Botan Benchmarks</TITLE>\n\n"
- << "<BODY>\n\n"
- << "<P><TABLE BORDER CELLSPACING=1>\n"
- << "<THEAD>\n"
- << "<TR><TH>Algorithm "
- << "<TH>Mib / second\n"
- << "<TBODY>\n";
- }
-
double sum = 0;
u32bit how_many = 0;
@@ -122,26 +94,18 @@ void benchmark(const std::string& what,
if(what == "All" || what == algos[j].type)
{
double speed = bench(algos[j].name, algos[j].filtername,
- html, seconds, algos[j].keylen,
+ seconds, algos[j].keylen,
algos[j].ivlen, rng);
if(speed > .00001) /* log(0) == -inf -> messed up average */
sum += std::log(speed);
how_many++;
}
- if(html)
- std::cout << "</TABLE>\n\n";
-
double average = std::exp(sum / static_cast<double>(how_many));
- if(what == "All" && html)
- std::cout << "\n<P>Overall speed average: " << average
- << "\n\n";
- else if(what == "All")
+ if(what == "All")
std::cout << "\nOverall speed average: " << average
<< std::endl;
-
- if(html) std::cout << "</BODY></HTML>\n";
}
catch(Botan::Exception& e)
{
@@ -172,7 +136,7 @@ u32bit bench_algo(const std::string& name,
{
if(algos[j].name == name)
{
- bench(algos[j].name, algos[j].filtername, false, seconds,
+ bench(algos[j].name, algos[j].filtername, seconds,
algos[j].keylen, algos[j].ivlen, rng);
return 1;
}
diff --git a/checks/bench.h b/checks/bench.h
index 07d67e0d1..0cc3f46d1 100644
--- a/checks/bench.h
+++ b/checks/bench.h
@@ -25,10 +25,10 @@ class Benchmark_Report
void benchmark(const std::string&, Botan::RandomNumberGenerator&,
- bool html, double seconds);
+ double seconds);
void bench_pk(Botan::RandomNumberGenerator&,
- const std::string&, bool html, double seconds);
+ const std::string&, double seconds);
u32bit bench_algo(const std::string&,
Botan::RandomNumberGenerator&,
diff --git a/checks/check.cpp b/checks/check.cpp
index 678cf4b09..30ee90d98 100644
--- a/checks/check.cpp
+++ b/checks/check.cpp
@@ -94,7 +94,7 @@ int main(int argc, char* argv[])
{
try
{
- OptionParser opts("help|html|test|validate|"
+ OptionParser opts("help|test|validate|"
"benchmark|bench-type=|bench-algo=|seconds=");
opts.parse(argv);
@@ -113,7 +113,6 @@ int main(int argc, char* argv[])
<< " --benchmark: Benchmark everything\n"
<< " --bench-type={block,mode,stream,hash,mac,rng,pk}:\n"
<< " Benchmark only algorithms of a particular type\n"
- << " --html: Produce HTML output for benchmarks\n"
<< " --seconds=n: Benchmark for n seconds\n"
<< " --init=<str>: Pass <str> to the library\n"
<< " --help: Print this message\n";
@@ -140,11 +139,9 @@ int main(int argc, char* argv[])
}
}
- const bool html = opts.is_set("html");
-
if(opts.is_set("benchmark"))
{
- benchmark("All", rng, html, seconds);
+ benchmark("All", rng, seconds);
}
else if(opts.is_set("bench-algo"))
{
@@ -156,7 +153,7 @@ int main(int argc, char* argv[])
const std::string alg = algs[j];
u32bit found = bench_algo(alg, rng, seconds);
if(!found) // maybe it's a PK algorithm
- bench_pk(rng, alg, html, seconds);
+ bench_pk(rng, alg, seconds);
}
}
else if(opts.is_set("bench-type"))
@@ -164,21 +161,21 @@ int main(int argc, char* argv[])
const std::string type = opts.value("bench-type");
if(type == "all")
- benchmark("All", rng, html, seconds);
+ benchmark("All", rng, seconds);
else if(type == "block")
- benchmark("Block Cipher", rng, html, seconds);
+ benchmark("Block Cipher", rng, seconds);
else if(type == "stream")
- benchmark("Stream Cipher", rng, html, seconds);
+ benchmark("Stream Cipher", rng, seconds);
else if(type == "hash")
- benchmark("Hash", rng, html, seconds);
+ benchmark("Hash", rng, seconds);
else if(type == "mode")
- benchmark("Cipher Mode", rng, html, seconds);
+ benchmark("Cipher Mode", rng, seconds);
else if(type == "mac")
- benchmark("MAC", rng, html, seconds);
+ benchmark("MAC", rng, seconds);
else if(type == "rng")
- benchmark("RNG", rng, html, seconds);
+ benchmark("RNG", rng, seconds);
else if(type == "pk")
- bench_pk(rng, "All", html, seconds);
+ bench_pk(rng, "All", seconds);
else
std::cerr << "Unknown --bench-type " << type << "\n";
}
diff --git a/checks/pk_bench.cpp b/checks/pk_bench.cpp
index 8e5054a9a..f99a13a93 100644
--- a/checks/pk_bench.cpp
+++ b/checks/pk_bench.cpp
@@ -603,7 +603,7 @@ void benchmark_elg(RandomNumberGenerator& rng,
}
void bench_pk(RandomNumberGenerator& rng,
- const std::string& algo, bool, double seconds)
+ const std::string& algo, double seconds)
{
/*
There is some strangeness going on here. It looks like algorithms
@@ -675,6 +675,8 @@ void bench_pk(RandomNumberGenerator& rng,
benchmark_dsa_nr<NR_PrivateKey>(rng, seconds, report);
#endif
+#if defined(BOTAN_HAS_RW)
if(algo == "All" || algo == "RW")
benchmark_rw(rng, seconds, report);
+#endif
}
diff --git a/checks/validate.dat b/checks/validate.dat
index 05a9b98bb..287c068b6 100644
--- a/checks/validate.dat
+++ b/checks/validate.dat
@@ -19472,7 +19472,20 @@ D261D6041824D259290EABD3E9132DB8:7E3B14847526572FF2AA5D7BD626B560:\
01000000000000000000000000000000:07E5E5AD7097B849BADC2D5D803B7F6A:\
0000000000000000000000000000000000000000000000000000000000000000
+1032547698BADCFEEFCDAB8967452301:D5BAA00A4BB9D8A7C981C8DC90D89D92:\
+FFEEDDCCBBAA99887766554433221100
+145F0B8B663176B95DCAB7E9DCD5CC24:1032547698BADCFEEFCDAB8967452301:\
+FFEEDDCCBBAA99887766554433221100
+
+1032547698BADCFEEFCDAB8967452301:DA860842B720802BF404A4C71034879A:\
+8899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100
+
+B2696BD0D98C17953E4239225D27202C:1032547698BADCFEEFCDAB8967452301:\
+8899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100
+
+1032547698BADCFEEFCDAB8967452301:93DF9A3CAFE387BD999EEBE393A17FCA:\
+00112233445566778899AABBCCDDEEFFFFEEDDCCBBAA99887766554433221100
# Corrected test vectors, based on NIST's clarification of May 9, 2002
[Skipjack]
@@ -22938,6 +22951,51 @@ B4ECC305C3DBD8E5:FBBEC8F5DBF4CEFD:1B5E23EBD915C1FEE59F57DD91AF7347
# The block cipher tests above are distinct from these ECB mode tests
# for testing reasons. They could otherwise easily be CIPHER/ECB/NoPadding
+
+[AES/ECB/NoPadding]
+D8F532538289EF7D06B506A4FD5BE9C9FD7A929E0FD917686D9520ED236A276D\
+69E63C821F9DE0BF23CF1D19C7374FD1C3139DE2E1BA4693C3E9D29D774C2FF4\
+69E63C821F9DE0BF23CF1D19C7374FD1C3139DE2E1BA4693C3E9D29D774C2FF4\
+D8F532538289EF7D06B506A4FD5BE9C9FD7A929E0FD917686D9520ED236A276D\
+D8F532538289EF7D06B506A4FD5BE9C9C3139DE2E1BA4693C3E9D29D774C2FF4:\
+FD7A929E0FD917686D9520ED236A276D69E63C821F9DE0BF23CF1D19C7374FD1\
+C3139DE2E1BA4693C3E9D29D774C2FF46BA2DCF84C0E7E4D75CB53AD11BA76D6\
+C3139DE2E1BA4693C3E9D29D774C2FF46BA2DCF84C0E7E4D75CB53AD11BA76D6\
+FD7A929E0FD917686D9520ED236A276D69E63C821F9DE0BF23CF1D19C7374FD1\
+FD7A929E0FD917686D9520ED236A276D6BA2DCF84C0E7E4D75CB53AD11BA76D6:\
+00010203050607080A0B0C0D0F101112
+
+[Serpent/ECB/NoPadding]
+D29D576FCEA3A3A7ED9099F29273D78E2D62A890CEA3A3A7ED9099F29273D78E\
+D29D576F315C5C58ED9099F29273D78E2D62A890315C5C58ED9099F29273D78E\
+D29D576FCEA3A3A7126F660D9273D78E2D62A890CEA3A3A7126F660D9273D78E\
+D29D576F315C5C58126F660D9273D78E2D62A890315C5C58126F660D9273D78E\
+D29D576FCEA3A3A7ED9099F26D8C28712D62A890CEA3A3A7ED9099F26D8C2871\
+D29D576F315C5C58ED9099F26D8C28712D62A890315C5C58ED9099F26D8C2871\
+D29D576FCEA3A3A7126F660D6D8C28712D62A890CEA3A3A7126F660D6D8C2871\
+D29D576F315C5C58126F660D6D8C28712D62A890315C5C58126F660D6D8C2871\
+AA26D561F567520E8AE47528C24C18D731A2193D9A97FED6922B17AAA6372B74\
+BE5DEBD559E303C9C92B174A5107BBFEB626D8F65EDCCDF3AEE475C8A1837722\
+41DDE7C1F1631F5FDED4F42746471BD651D238BA86176EFE39E4695AAEB73B52\
+EA5926CADAD8018962E469BA920CB8BF1EA9062E4D9CEDD5FAD4F4C7990367A4\
+B966E5C5D2277288C61B96A559CC84AFB6A6583C5AACFCD6212B0BD8AEF3C6A9\
+A11DDBD175639341052B0B384678D8D9352299B71DD880E29D1B96452DB86540:\
+B2288B968AE8B08648D1CE9606FD992D717EB02EB81A2E939D54ACA91087112D\
+0D809C5EE82F477EBA7B956DBB23463B0F0190D616F5294112FFB7884E8B37F9\
+41BA1B505386B7428B88338188F7E718A3348230BF5CFA552F88D22463D9703A\
+115351622E016BCA26918D17E13225F67EE4E3F2C46FE52ECBDA044C585717DC\
+563A8403FF5309D62370B1DCF5A11EDD2F7D73602B70CD2553E44C1D3F170126\
+155BBD9BE3A965B345E834718F651CEF6CC65E8C5C566E894817350F497816F1\
+EEFA51FC91FEBB6E9F8CB141CC0EB6AF3C6F8380CBD3C996167F2F0E90E71B75\
+6C87EB62A4975356B28DCBF6A64A0BD107206D48FE6DBE19D50314B90AC87B83\
+35706F9B26007071AD8105CFAA1C1E2FF7FEAE5CEC4D11477F24E6B200906870\
+3C0E29E2950F2AC2DACD63DEEB5C7EFA9FDB9F3B740563D5518287DC981FC9CB\
+46D4B5A5A86FEC08FE70D18297DCF51072DDBE038DA040EBB12C509F5940A212\
+DDEB59F02132BE4581FC23EABAA960D6341D9352E36DFD6E4EAF0F6F439BC8CE\
+73A9AB3164FF30350F2DC08E939A104D6DF0C2C28F8E2D44468A61278BB6B429\
+4DAE45AE0CAA032FC97CD4D8C57FB83BBA8AFCAE22070BC882D3A42B38A09E65:\
+00000000000000000000000000000000
+
[DES/ECB/NoPadding]
059B5E0851CF143A:86A560F10EC6D85B:0113B970FD34F2CE
4E6F772069732074:3FA40E8A984D4815:0123456789ABCDEF
@@ -24214,6 +24272,1007 @@ D05BC090A8E04F1B3D3ECDD5BAEC0FD4EDBF9DACE45D6F6A7306E64BE5DD82:\
FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0:\
9A785634120000000000000000000000
+[Serpent/CTR-BE]
+F3:3A:\
+740614949B42870F0851A0D639A37AC8288898B0F9CC3B326B983ADA69BDBB76:\
+3377FFD0C8093067A0E33B8700E2C2E1
+
+3018:053E:\
+872BCAEFB1985B9C10B1F2DE2790E22CF31C362AC7276D437D0DD697F1682BC4:\
+53C8B7C9BA119E81AC5474FB70BF82FB
+
+C503C6:DC4178:\
+DE3317D05233577D476509E638486ED2ABE26ABFD847C13A8AAB189F322F46B8:\
+47D690C680A567B9942BBD0A2700B884
+
+FC9B1F9C:89FC80B9:\
+A2B4D60F8F9B35C56168D80E8828F3931A5BDA190E65B9B06A814277DB2B4F63:\
+B3B98D928D3EBE1B9E07B291ACF9CD2A
+
+F1CDFB642B:2BEBCA6F33:\
+E39D7D09F410CDC21333D8EBE5E33E7A2E24872A99254AEDAFFC633061C32EE6:\
+107FA9631083DE98F5C72A383F541F3E
+
+9C3BACCD6154:DE9920471C92:\
+9F7268895714AFE229162D50CA59F1273744BDC28B198E1685F4323AFAE1243D:\
+68C5EEB64FC3DE106B99C0896CC0689E
+
+B5602241E6ACAF:2FD52D0292019C:\
+27757554DD1B5BE2E660576FBAEB238A0F7642F9A65771B69AF276A57FC04354:\
+9BB3DB1661C90DE853294D20A369B999
+
+8E27C11E30E23C5F:0294FE7CC3F020FB:\
+84688112BE481C65B282D4DF9A953526AEBF05FDD2F3D84E7C32830E3BC185C8:\
+3ABFC6E1B2358A3B968E416B9087BBD9
+
+A4CC3F182076E93409:00EE68EB6CC635BCFB:\
+967BA8A79CCD302B294E519813B72EB5C4D24BD86322FBDE08C292C2DC4723E8:\
+D7DB3A2BC532D1F1685CB612FBCF33A1
+
+25B63E2B38DFF81FA490:E75F1A6DF39CC7A76D12:\
+6757B7CA6D7EEBFD0E679E18CB30D16ACC71D0B1A149DA27E439DA1BA0BA37C9:\
+3199830075CB5E87016EEAE5B0B26F13
+
+310605508E614C101E829B:366A5DCEB8E76183C95CFC:\
+F92107A1778C99C45B4E229567BF5CCAB2C5B1204052B8720161AEDCCF57E36F:\
+378D5BF003FB48A4D183D5227151FE11
+
+6A706D5F6526ED4AAEE00D7D:8145258ED5FE88C34E671101:\
+F892DD670B66CCF6B8E458A6F068FBA79F4A69AE3A028E43D8E219BE940BB826:\
+08BA9435AF764BE0E44515FF72D6DCBD
+
+FE62E34899D4115DF7FFF51A8A:66F68C5AEC9A4BB123056667D9:\
+BCE52007E10A2CF3077D00225C95F2D68FCDF380AC17304553FBC1DA10117B15:\
+3FFED78824BEB8D6D655CC80190124BE
+
+191D3CFE172BEFAC1A8A428DF951:7CE0D419C43342FD2CD8D56685BF:\
+534A1F49FCD2D99E2ED2F094E170809091195EDEA2ED94EA4DEE64F9A6F89E05:\
+D98E8D86E9BE95318429FD7286D528E5
+
+2C92024B2587851C0F58C91B822DF6:36FAB117335A5F0C619826ED801670:\
+41422F58E73BE8C494D750910CA612B2FDA0A41D041ADDDAB4144DF30CE7B26B:\
+DF0771CEB11F1BAF934289FA42F54319
+
+0CC08B6ED36673C0591901E14AEF4792:250C9E812F38A9192CC65C6EE5B9DB60:\
+EDA2AFF3C4923D3CE745EB78655B0D27DBDB5C584AFE56564C7B625903CED927:\
+95C67856E6EB7B0E98F0934A47DF6485
+
+C6B6E1F1BC46E8377F6C397C136461973F:AA0C36B960BFC811185F74D22356686414:\
+D4FBFD37C5B9D12E5E43D1867E1692A2B331CAC9E6C46C228A45E95AFA303185:\
+30B9693B12B7F48C1C07F1441706821D
+
+CF1DAFB2581C47D06D8F178787729F8FF457:\
+10510051990A826CFFDF9014CA0B49481E39:\
+47E9CA81E014F6AA4F94A7C0B8A533B7A636FF14E76935D9C7A3CB01E3AD64E9:\
+DEE733BD4644E258CF98F7FE87AD8E5A
+
+EB95043E36EFDF2B5FB8F17B6806B2B021D1DD:\
+A739171DAE7EC95CEB492183803D37165D1A79:\
+6BBA2F42B85C58A4916F618A294553E084E223739F575159DE9EC4F5A63F3AAB:\
+0DCA755F625F78C363AC7EAB801DD471
+
+3277ADC7055990FDA21C89F183F0A380E71B696D:\
+610369449E344D609EEB89210AFFD1C90B05C197:\
+F3702792DEFB775F10B142CAA78D05DB26A4A8061CEB39FA2B4A27106DE8D9DF:\
+5C8EF39AE0EDAEB76CF3C10B94D1A002
+
+43733C60414C054EACF68F85C67D547AFD0003AABA:\
+E8F7CCA960B713991BEF20DEB3DF284ECFE912B479:\
+AAE83136AB1EC19B3BC892B0B5E8EC7A6E20FF5AC6C126DAF6189A7E2E344AF0:\
+C99EBDE92D57326A37B4B6F2C19363FD
+
+E2ACCDA4075886B085C7A7B71E39BD23F71DD16BC4E1:\
+7A0552BA9DBCE00A60AB31F8D0E590D79E2EBFC49713:\
+222373452D105C2F58E87F5DDDF07FE464E47BC8309718FB30674770CA24FD34:\
+A03B629DB1C399F8EE32A7C08C0FDDB3
+
+33CF3C69194FBBD03B0496F1982C570B363DDE621303AE:\
+8D2763FAD25E2A3BA7F4EE3ADA3CC05310B453734EEC56:\
+CCD9F95EB29B2609CB35C959009B56FD43A60B4353A2F3D60FE78F2219074330:\
+884C24E8368B3DB123F47D03F3812F12
+
+32DE0A03F6D52AA26BEECF4AB22ABF3A49768683F86EA983:\
+D4EE5E9BD04A09D73DFA9752A8DFAD00F151E822052B500B:\
+F7C88B964D55E40A04D8016900A3449015D6324DE16A024C0F9FBB1DE505C1AC:\
+308E6F85EE34ECE3C70C1EE2CB7E6777
+
+52F14AAE8ADB041BAC458EF07FA247FE50B868888089587933:\
+BE61DB06D28CA4D3B418F10F463FC42EA254929C5C87D35418:\
+972C448AA251ACA8F589BE0F5793100D14EE3282DFB321CE5943FDE99D1F31AE:\
+11C202F46DC54AEDFBB543C3A55E7DB8
+
+E56DFAD59ECA41C38A68C64388CA4D2CF94B319C65E033C26A8C:\
+DC4A5B96090CC569B623D54BB1DAA4A7B6D879F21BA420D80637:\
+DFFBD3EA5DB1F4D7D9613F069BAF8737F0E37A33BAC9A9AE2EC67FF20E37442D:\
+17E670BC9C590D7B320A233232D43311
+
+A89CF708448D7D4B1BD8C252F9EF7A0A7D978A1E862713F807E0FD:\
+A244860FB2E83D608B25D77ED4EBBCAA7C2AF886708002C77EB5F5:\
+A14BB231478EBDBD7B6A7D7039559099AAA281D25D095F286B8104DF77DE0C8A:\
+5410153016A90F03A3863EC58BD66004
+
+BA6C11D80E304AFD1D922E2B35A47C3ACB34F7DCB7826F76A3C469EA:\
+CE19CF171B181B3CC5261B5A38E9142DA7479F88A9B0F7F63E98BD7A:\
+B5C0F5A46D855F6CE47CAC0198FCAFB7432AF8810A3746A90CB440DC2AA1CC9C:\
+A1A57176001EF2B0417FB7DE1630AB54
+
+90D97D574AFA947AD194F3B94D17D83073D6ECF2FDBDD5CEE09D3D553C:\
+5139448ECB4D8B454563FF5BC6CA47D9BD23329E772F03E4C661E4CFA7:\
+D684575372F4EC2F0131D786EF6B9666C38D2E99C2DAB7ADBD1C9FC805DA4229:\
+81301A434C73C64DDB94440FC887542E
+
+F4C312864C4FF38BA8D285608FC924DE8E60F4FF0E603AC7D3548CBCE1AA:\
+04823EE2C43AE04312C6F538F03DB4635D13026D546254A1E0BF5AF97B58:\
+7C3F63710A6B10B0131C5BF96BCEEF6AD226FC25880A975E355CC2547435D861:\
+B3F1E356BDCB368C8F1D306DAFF59684
+
+9F188A9CC6957F8408FF2A93AECEABEC0D6484AAD13C88060CFA7C52F55130:\
+FA96B9A0FAA199FF22357287FA8DB515ED3D522039C3FA649E5BBFDE5D0D79:\
+8C263F3C683F2C78E8607AC7E79C703F0F1D872BFFADB07CBB9E07C62624291E:\
+1BED13CCADDA5A02EE6F3F529A7A97A0
+
+6F129CDB56D48914EFAE7A534C33D03280CF30D12389EB5119106790B84BD73D:\
+29ED54DFD26F097312C42848BD496B78436F907238EC8DBDB5A22FFD76CE76D2:\
+69F48BB5EAA67974713FA974EE645B5DA6B8E5665CE0E40347575D050755EA6A:\
+CD6E4DDE0DEDEB87B7BCE9998F41218F
+
+49407E33C46EAFB24B01BDF5300DEA35AA5BB5AEDAAA2B5E47B2B63753A44F71127F:\
+DC0A9F56FB2F440305B288C1C0CCB896B21D89FC3F741034DD76B6887740C5CD4A20:\
+3AE57D49BAE4C54AFCA650206B3FCBA71306286F1B9A51624CE3CF08B5791CB3:\
+75D84A34073AA6331A8990572C5FF55B
+
+C34EF208CBE5F148CCF3E005BD2168C8D8346B18464EC8A6C8DD156A3ED34CE35C2A16F2:\
+878A83F17390490E68D50937BEC73D4A5BD4183ACCEB0D582464DD9D3ADE683E830E8C24:\
+F39D1CF76592D48DE487808FBCA14585C15F29FFB7C9EF9A4AF74B1DC29459BF:\
+50FE7E7F598B4FC4D0FF6D256135861A
+
+6732BDCFAF3C9681E5684208D5C49354C8C221FBB584080639E3A66C0CEFEE4662BCB787\
+FFD2:\
+2B40579DD8E87440DCBC664920573309D3342DB52463F76FC7BDDA45861F8775553129F9\
+48D6:\
+8B387194C2E79916F5D2B5E3145B4F7CBDF8190EEBD05B598A3F44D1480FE045:\
+6C7EAE05E72898C271A3D7F1668532FA
+
+3CC7B907609C374805F3E0625C2A8B77BBFE8C22860F749E4871541D27BE589B21773489\
+E08EBFC5:\
+FCE9006F2073F1C64AE42908C2E7F21EF88422526423ED8E341F869B2EC8E9BA679E9028\
+102C9BFC:\
+60FC4F62E03E3C0ED6DD21259BBF3D4C24031DFF6A20ADA2E2D637CD0FDA2351:\
+6BC92664DBE433FC2580850BCF0E08DA
+
+741C912167AB5A5AEE918FB21480A2EAE39C0038A458A34D4AF86F6968A97A945B4EBCD8\
+D74E5C1D7388:\
+116F94F7C970083C2F918454F7C5740F3F92FF83BD5A0C5F8DE592FF115171711879C6FA\
+739E14D0AFD7:\
+DCD3F3A96FEF4C6DAD109A65D574842D04029B155BEA7AD54D25D3FF8FBE5A2C:\
+DB7728ACBA219FE1AA8259448BE3D6DB
+
+CAD05D525C37CA43C187403F3357EBFB580ABB2F782CFA7B9661B1F71B1809920EF0D897\
+13598CA4749763DD:\
+C17D53A4B37EF4AF33DF4E0F317BCF8541ED66DFACDA662289B261ADACCA3D4C0066159A\
+BDCB108BBF5C707E:\
+0CBD7326ADF581A058CACF74A3404D3CF9EEDFAEC8E47BB30BC1AF1D3660E0E4:\
+C4DB5DDFAEE532C12B7313A9258CE63D
+
+6032DDB7CAAC7CE2CCFFF53592FE2F40280F8C79E312F4DDE307E90863A9CA18E320E0EF\
+27B21216216FFA8EA570:\
+5497807495FF72FFC8C994E00CB5E7F5C521C86965FB17AD3578EE6240233A7E2C9FCEDB\
+FF7F1B05FC6DACF4A0C5:\
+567AF81216E5B25179143BC1C3AC52D940F93EB4EAAD54AE0A6F33661CBE0EB6:\
+EBF6B3BFE42C2AC5AD0B02B7D294DFBF
+
+F3DB2D14DDC5CC45CEF2986CE9775A64C435B36D305DB04A75FFD3BC83ADB8595397EE9E\
+1B8137A8227535B3984A7267:\
+7BCED3DCD661CE1BFF9A6D1B52D957D12E657DD6241F64528C496B6D5A729783FA011AD5\
+788BE7DFF57D892A0ECE7A92:\
+818DD281DE7C051FE22A5CD1FF0154293556D693427EF49CB72D31E05B91FDDB:\
+4A3F1F5AC035B0D18543BC763D42D61A
+
+83EF6209E5EC332E9CB0A2F73EEFA34EDCA0DE7148188A5A5E8AF5812EC9F272147901F3\
+8B811FB759DA8060A1F93E972204:\
+C4D6D68DF04F55151A46D291F188C71E3C59C06319D4A6B40B86312E93ADA7EE4CCF495C\
+D56E0610ADA4EE49EB4982601DA0:\
+06ADD322678535E83B950851EC12D6DCA818D19F1041F69919A1E0A16D868ECE:\
+8842C25CB6F1E93F2485204B8DF65A61
+
+14D9C539288AF393FD3552DCFCFAA4EF497514E7101ECDC92E875BE2D958D296FF1BE307\
+DC5AFD29F71460DD7F093A392C8210AB:\
+792DBAD92AF1F5F5E5AB14060E6245D4175A6D73910FBDBFF76A08493464827A108141E3\
+83E3104E3F4B7EC645FEB7740A426AF5:\
+2638477FF92C0A140CA99B62CDF46452AD58B01A2DA667BD5EB3D425E9EFB5C6:\
+FC9E9308891984AD0B305CF160A64B45
+
+C4E76E643B92D878A7BC2693EA1D0E1E86A06FCCFEFBD91506D2B8C6024490FC965F037C\
+EBA97C607F808E48C9D86E40AAEA079FA7B6:\
+66BBC945447CD9FC87CB47AE7F72FCA83696BE3BE6396ADD9EFAB87A3BE17718CA2E49AE\
+00758AB922A2F2049BE84577DDFA228918C7:\
+ABB8BC67A8299C34C4B97105230E203F1BF8032C876E908E6024F31F0778C2DE:\
+03C8C55A12AFBE4B5930A8D8FF80F1C9
+
+C8A5C5A939F5872E56BE199D24422A7B99F797617B5E39E02729AC05ECB1990CF8D287B0\
+8A718495D9F261E9110E4EAD62AC789918CF1CEF:\
+23D2A8B6508552F2075D340707541547F37E622DF4DF55EE3E0F4E0E610216B7E4218358\
+ABFD86EF3A6A5739A0EEA49267AAAFD89B28D5A4:\
+5DBF7CE56C2C431FC9B69EB80635D0B7BF58C7860A1EBC876914BD040978391C:\
+9E2DC1FD8EC1C9E1FD0D5273F1379D46
+
+37B26B33453BC31C69BD09D5778E04AA8F5FFD7F367727B30246C81BB92F9ABC3DC9EF72\
+171C3F38B76CE887F647AE42D87319D4209857EBAC0F:\
+8F85405DF5DEA595B58FCE86713593BEAECD39B4F4BD11B43024A5FFBBAFA0F4817AD6F9\
+2C111C08506056654E003CFF9A60162147ABD56BB4D4:\
+6A3CD1AC06DC7198EB08F439CFED766EF40551B1361048BD17B1A88E9447EA27:\
+23783203B030B2AC2AF81621781FB946
+
+44DE8E16D60C2CCB0E804ABE95CCF7CC597B1A9D0B3FD15BA2CE321273006322B4EBC4B5\
+BB90E1456947B3B289A9F6DF266FEA780FA13A2CF50A0882:\
+03BEF28AED188F7AA6128016647546160DDDBE80BA403CC4F29D9D90A5761075B170D1E2\
+7EC6ED96E7A329ABF59F7016F4BCF39F61FD82C010B4F7A0:\
+1CA7FD4782991006FF0246581729BE4341A6556C61FEED749EE9F48DE8037874:\
+7DD54BCD7665BD84E8DBC84F367AA008
+
+8136A889B8105FBAB44325DC6114F395CEEA87EB6E69D35C6020AAE00B47942B262157FA\
+273B2317CE08255AF899CFAC6A83AAB7D4C5FE5729A64AD9F8B7:\
+2D6B1B438E8F7A70555902ED6FBFE2ACFC371DE250F32C9D5B75321913837E36646DAABC\
+E5B69AA971A0C6FFB5928E0A75A13E004BF241E73754B74F3947:\
+9E8BFDA871A63F32DC05F53D1859291E6B099E2B4474A43E570D6D167A2E99A9:\
+51027A0552EBF97D8372668BDF106F46
+
+80E71459F0F7DD4E490FFD23063D1F741E44939770B6128F07BBFBD48323A2CC7558A4F4\
+CA4FD9C32A137C5AFBDB278A9ADCF66B0CA5086D0C09126A7FD5D20D:\
+AD68A517A73C9485AE996D79B90344B5ECAE6C11EABC4F268B165232F7A062F73FF46E7C\
+674C706F14BA70EF9C77D5E6DF90CBE09114AD4E60417A597FD896D8:\
+9ACDD36A9AAF77D9E2C6286DC456D461508356818F4FC2CBD001A94037E42E1F:\
+0EB87233AFD4C552D9D5ED5C415F03E7
+
+0EFC9979CFC65020583D4141A6422CECFC1E816B8682A1BF73D05175E8A2E83DAB239DB1\
+5DC57C4ED427EED3C73491285767EBBFA20CCF1CCBA594FC45980A34C659:\
+ADECCA8B5879B64CF35C8AED809570D12BA0C0EB19C319C0B9FB1A0A33C04F48E2B755D2\
+CDEA8C0582019F7847DBCEC023A4AD27CF4879C07CC33CAC9DCE9C47A491:\
+B0B664A621FDA57B3DF93323B61DA43CD55EFE1B1954A8B86CDEF4963E082B5A:\
+63DE5E4E1401030D736BC327D9DB2BB8
+
+FD8A05EA9F872847A37F33D66906C085D10DD980435028CC0F7FA168CE8363A8A5420E33\
+67DC06AB69C2DDB49C1BC0E32E1F1316EEF18C01A95C23B3342ADA89C131E42D:\
+B0A2C09A27F4128353DA11A0797B63AB54E2CE00BA58BB765C8F6F65930E69258F2C3F30\
+914FA964AADEC9B8DAFE39C58757D65CFF6702B955550C8A494B64056B906FE0:\
+6C62EF4976E50622F623337E32D70DBCE1E423B4CFF652C2ECB1D3DD194B8722:\
+B7F60B3D94FEE7768CD92148FAFEADC2
+
+A592978733D8647858659889303CAC080E95C2B2B26642520CC6B8598C146DDEFBE1E4C0\
+68F3FC0BE9CB0EF3D61000F2E688AB2D9DE7B7A28C3B32AA3F8B872F91D2CCF9C927:\
+2B3D0D935877281412DF2AD20602D0AEB7E375826BECF964E5EE29A8EA1B20529943BE59\
+5C099BD2EA0F70ED95BFF11FDD52069274E8D21B00AC5EA11369BCA9E6052F1ECE13:\
+85357F480C3AC5C8E412523D2C6D45862CBC91394DAAE40BC20C58DC7FDC113E:\
+CB11FF4AC49C513BD56A79104FE48F89
+
+60C42D6EF79C6FD920FEB2A9EE00EDDF34B3339F99BF13ED42FC65247166B19C42099DA9\
+089F8131856FAC9CF0703AB9C73DADDDF700290479146F67B49770CA9B53511D94F6D7A7:\
+35409AEBFB98BC6CC70BE661EADF99C7E1133F912D8FBB957A5A61AFC01E622864C1AD2D\
+B0898B0D3682042A510D65584C7EFE9517D0CEA31D3385C857AA334478BE651DC48E81DC:\
+53286FB5B6E08E9177CA17919D845A958B7D55361DDE5E9B09B40138BE3F68FA:\
+D7FDD75B3F672908845354CDA2EC33C2
+
+55204AF292A15EF0907E3A05FEF0BAB2FC199A874FA3B72B1959CCF5CE59B1A63BC7D0C5\
+709A1EE8152A11423FF3D021726C9B914283610530B80114A6AB16F1821434CA0B5B66C5\
+1181:\
+790F49950B195EFFE12FEE3DEE248147793869ADE0B46B412F702C4AFDFDC92A95889D45\
+F1828CAD935CF281BFDEFEE68057906564E63509A464206A3939C9787AF559C2F18E857F\
+9794:\
+CA1AA91974D69777335BD4CDE41584FE09A0F90B4EFC1DAB01F5F6EE475C5B26:\
+A753ADB21556F5166B8D0EEA24AF4D20
+
+F1B63FFD3C223E65972E716872206B656F036AB58CDC6BECF814B4372828651A28FEB0BC\
+6F7D5E008A0C9D069C5765D9613F75AE3CA564089840C2E5326AFCBB73E9677D60261C1D\
+11DDA8D6:\
+05C44E476B45156EFD1A73CAAE0CCB4A02E7A3BF461377AC5573624F3CDBB03E5F040EE0\
+0A628EAA819B84461B8F39D63308C5FCE21B823AF0508384E0A5784B99FA47AE0A15F8A6\
+31CADD11:\
+67EEEFDABDB4E221A3F5D331E021861D80B3E52EFD3662FBE4B7F96CEC220668:\
+ED8A0E2821ED9E46D9E47973CCF4FD25
+
+415E13F78C19D639C7E2A262D03D17C33648D7852706B0787C5DBCA2F7BC09FCEB3C570F\
+CF3E121AD6B9E467515998EA53B59532A5D0C86125928ADA505D07E9C0683F0F2862A0A7\
+09B76B9F3E5A:\
+96D6DA75EDA6029E162A70667227790B28DD1D08731D08024FA175861A30D321CF95FA07\
+A96077F5F9F3BD0EF809CBA394726CDFCED17507C89295954F7AF19E7CD513D18869E7B3\
+418E193DE7E8:\
+BA8A42A5079A1211FF373CADEDDFEBE4230384AE50C0CADB777689E9FCE03021:\
+F2CAE7EFFDDCCC54DB0DE734347ABA8D
+
+5ECB18F27BDBC1469A4EE7273423D51CF53DA0BBCB3773C04F90934DF1A4E686B76A2CA1\
+9B325F91CBC13CDE9FBE0E7FB1D205D78EB92DF19A5AD39D9E5CC07A4329EF14115D5A89\
+4F4669D6B6C3E920:\
+47D37261C8ECBB954E6980BE6EE8A89CC31E83CD8703AF97B40308FC71FD5C204C9FFF43\
+B35BC9709CF9089BE6EDA572EC4B580F74A3C25741B147D3F2D06A7C5BE8AA35DF232546\
+F93B603A91A4D4AD:\
+00B1CFC598BCD9B708AC9CC600AD951E95228C4941FEA43D3E9F9C4C4DDA9F57:\
+AAA2D1218D7E5586150602486330D79D
+
+ADCBCF6C2797D693DAECD8B395FF2D8951D9D58748398E1886146CF39B6BBE94AE5725B0\
+8DAE80061365508ADEA2F7E27006BC2EB8296E441D9ECF3A1F105AEB72A7B7ED65C0ADAB\
+96DDB4C56D3E6CE7EF9B:\
+204B284617F9E475636543C231788FFF1566DAA35B7188BA5502116479D8CFA3571726F2\
+3F83EE62960DE1C5512364AD31BEBD71778926B4DBA86C69C87BF62D590FF01D43A7FCCD\
+9DF526738DA3ECC07313:\
+D9E06DC86E89570392B95234B2B4DD1D424FB5D96D8E5EE6522EC023247240CE:\
+555BBC29444DF1C9B19DCC36E8F526E7
+
+D1E3667AE3F908CA70E42ADB571765C2977A7597AF1E93568BF144FE6B8774AEC889EBE1\
+C55EB673F2E05C9049FD38FA112413C1F5DAD6400104493225B2A1FA2EF314267671682A\
+96A15FED5A0920BEB7915759:\
+0D8B1A4D0B4BBA07DC3D66FEA6C79EB79845A303A99D0CA6A1363494FED39D9B2028323E\
+A66F48420620AE16522CA5C036984E431645D55BB71C9729786A2942D246763AE14D4D7B\
+E8182F4412706F88D745D29A:\
+8FA2C547E80F8370524EC80BE768591403BC8B84A31E823E1EA7B58D13C2C1A2:\
+FC552663E080DE3AF70F1843B20C2321
+
+9E66CD55C5F5ABE2D9F479572D1867AE07654DDFC4B09603A7268BDB98CF22A15EB207C0\
+5946957927BF3442FB92CDF2BC64CB1AAB4267884C65AB29F7C7F1AAA0C797DA1BDC2FD4\
+7E02566998933F0371F054AF75F7:\
+4998F91D12BD0CD7C9C3E4D7E4AFF383D87555C75523452F7764B8CB017DE1C9775DEA51\
+AC4A84CBC77FEA7CF4D4ADB3F79279E73EB443513AC9FBFEF3F210F80C553C758149CEAB\
+515578E988A8F49D4B87CFC7C3CB:\
+EA2BA62A693024D30A6F86F92534B011D6D8ADC81E6DF43A15F1A38B077B47C7:\
+B09F47C60D4A913E80DBEB9572CDDA2F
+
+0B515541E94644E05C6D33B0DEC22322A23EC8666C40697D58B0D7E28FE278DC8C6747E6\
+0924A09442A04C167D48CAB29D095BDCC0EACEED2C841FBFF1010769D8829EC1CABB235D\
+CEE28CC09C4D905CA1CC8BE624298D76:\
+0FAD0D901C43395C015B252EBF61F66FF41713C2DF9AD2245E1EC1ACBADD2007412DE768\
+E5C986AF3F26FC489676AE5F7507AF559A8A23B56C417FA1452D92CC6671F6E4BA5C1F60\
+819811F9704953BF349CA5C4D3A0631A:\
+E659BCA785C4BB8BB49DD36F132EC4984397B2665B97689FFFE7509F1A1D7551:\
+069C61C342C4DBEC240C709C3CDB361A
+
+D2C5A20331AFA2FC82F0A0D64160B4EC447FA5572A26EC3C64C9F736E43B0915AA7C3E1A\
+B6A9D36BE4A15CB26820E29AACFE83024959676FF05376C1AE788D276079F199936AED0F\
+0F688E42E337329BEF9336FFA36FA4005399:\
+7DB91F84F3477868CDC873EE908DDCAB90CBCAF18C0A70791A120AEC86CDB215E6221A70\
+14482F9E3802EA3467001D3601A63C92C6AEDFB4946845F13A52351CDCC6D5F922D19DD5\
+B1EC236E822F62655427E62A4D0E84914622:\
+FA7AEFC8F4B784C193C785B93E90D08F8523FF065E19B2F8CE817FB401A21FCA:\
+A66594B33C8A53C811C2D97CA6D14303
+
+7255CF6B4E647EBC0AC95A5695F0AF0E9AAF91E3D95749D6A49719093B1200B9C6BE09B2\
+6554E36EB6652041744605EB051062C0B6D1CC01257709F751EB7B9667AE7E329E43EFD7\
+44D96300958FADCA3C106AF1733CBCA1AAAF823E:\
+E3D3CF5237D3A038F5F6C89EA9FCA960FFF212211D3C2CB3490607C9957B553335B18C55\
+1BA25506EB2CC3BFE9F3EA6CF0AA9EC434AA592FF77B61BC06F0B2B95AFA8FF5FA494E94\
+DB731F57DE8529ED53A50C42F986C16EF7C7A940:\
+A26E2B0A05D0283D38D7169BC2BA47226EDD259B8D57B381FFEE069F1B98046E:\
+C4E7CE77538E9914BEEFD56DCFB571B9
+
+AAD33FEFE3F84DF826588A512B14CFCC1D853F2AB84203C1D4D8F8B86D6AF3F7173F6A6A\
+A73843D5658489507104DA3D7BFCF5168D986464C3448F234CA69BE3DCBB6672575564B0\
+2ED92FA0F3877DDCC06D502A33D6957A0E33F2DAFFC9:\
+CD0C9764841179AC19328315A39CD34BAC626AB5DB485D0F9B46059F54E08C5492B908DE\
+07B85E7A44EF9462BA8E0A81FD1220C558295A948DA4DAE908535719C1F88B1560673BD8\
+07F5262483B40AB9BB0C64926FDCD1061E504B4EBD76:\
+6EDD7092DA78BAC7E1AC92E3770134A03D2739FF5D34430F7F4D4D6E9764B319:\
+8AEEDB0DE46407E08707969C750E38DC
+
+8168FC2661FBA3600E59774138459C2961176EFC931CBD6B5C33560078EF7518635D6939\
+A98B0767639E0E93074057CCA6883F7964A1668FF9F8210E95D0368F6FAEE9FA8D7D7779\
+2AC00EA2BE1146BF56204FE906FB865AD039577C01234AE2:\
+51A47CF78D2484F3451F0C2A43EB428379D1F6893C1B8A39FE3E60F685DC87C0B840E9B9\
+6FF58B5D5FF56AF2D9E6DD1B2701C68A0E845D4D5976BD315A353D67347BC8730CA8EFF3\
+AA0DF4BD6DC8E05F7EA07EAF2C39D7D47D9D84B474E7ACE7:\
+BBF6DF7DBF4037FB25B611E6A2930DABF072F65AF0A6457CB9DC93972E9ABE7F:\
+501092F826689BCDFE80F092C26B5EF4
+
+81EFF330211A83455CB238BAB684E0067FE4067B8C991BC1AC8E7633D080339190E5D94D\
+B793154FC74FB0AFDAED0804E3C1CB51D2C1E13041FB81B2157BC60C1FF633D16CB4B9BD\
+331420AA12B95CC7AF57C713C24B727846B0C7227961F2C2D36C:\
+6886E3F70FD5F90852F3CE559925D769036D93CE8D9476835D517E0FB32E9C96D0388391\
+30C1C25E1B169ABE4BABA9B82C4ED74DD45F597867C5D53A0506AD37542F25CF58F4A362\
+BA222FA1DE9038A8FE543BBB44D85B2E0E4738067BDAE5DF7060:\
+432FFA626DF2A52CB0571B6E90C61ACED99991FCE9C16BE3B63F32BE944E2E56:\
+5C8A73A4AFFAD697BA8B1BCD810D8F11
+
+EE2EEF94470FA795A889D2669CB2B80D3155C8B61BA73019CCEEF203FA4EB1D9AF6C1AD3\
+B2954F7315935535333C758A4EB3247E19B07308569400B897322A4752612F0FF13FF3A5\
+361DFE0DAA88394F3642B1C6270718F28BE8C76C89ED29B6A6B0BF94:\
+BA17AF1457C42E6E6FDF4F98C8E45C0FF78D4849039ADCE1A168A6ACEEB9F419F49125BD\
+F26E443EB783108219A2841F82499FCF6870724044D9CBD95AE1F4E2A3D4A4C44C54B2D9\
+90E0DEFA120414ADC438E66B298B72EBBFDD7BF38EBDC44143E16B69:\
+A249D7A363F984C302E92C5F94F8896DF3F776225C022878944FE2C2CC5B4C19:\
+5EE7A0639A58783D7E82D1FE5AE0DE2D
+
+577B77E72EFE7CADFD281160BEB544AF2F28B41CFE4B92C5D770B322D40DE7590090833A\
+12EF4FDFB0EE57CE0A4A36AA71C0C39B33E78EC4CE15CA6400936E1561FC6206916DE9B0\
+3BEB08F90930048F493C05BED453ACC98FE7AB2256B5271A1E8958D07AD3:\
+A34F475248B72AD9BA2F461A690921544CAD263EC739AB3ADB4E42652A547553B3A303BE\
+29F23BD9BE7977D6750E50A2106ECF52C0A6724AED2EE8D482D09D0D2B9AFADB78B357EF\
+0F52E027243D445B5066572B0CF8812F3E19475650FE85DE610EEC640091:\
+AFCEECF27458C2A9B8F34603C639A5FF1250F1D6DEC2849F0D74BFDFAAE36660:\
+5C453B6546216E318A6036E803322401
+
+4A0F51F3716D41FC3E5264557D19CA35FE3B70E215AE6DA3990D1EFE383B9DE7E50DD085\
+5F751F95BC093EA76843089F284CA6176D2F25999230F6A5B9670059736CE084CC167274\
+9504BEC04B22F26045366030599337D1DCE783ACD0BDECB76DD4E9E8D4BE9421:\
+D747558707BE24371EB6DDA6B5FF138987CDC42BFD71D75BF1D6DA35591E4B35C32F9F07\
+A1C0B82A55AD28E4DFFE43764A814CA13D60EEFBDE3345BA454D49179662ED53A9F3FFE0\
+92D8DABE481E3DB0D7E34D6296102BC45D61E1719C864FD26FCACFDBA986A6F1:\
+EAA4738DE7B609D36A756B5DCEA1CF8F4359248FD8A423BAA925F0B6BCA7DBF7:\
+7DDE259B3EC5CD93A2734626A9B99FF9
+
+D8D191D620CA6DC8AE66658AC39D87B8465D32BB2637128191F0F92E47C7E99E01FD4B8A\
+8BAF767C8D66EC280C77E877EA06435A7EB72EB477CC2BB6DE52160E7B66F305DF97AC35\
+C821F418E1FC56FF8617B9B595CE824207099A8D9CFE24B616F14EBCFAC508C37127:\
+6A320C22C68E984F0308A5D626C16343D268693F283FD71885860FBEF767B02E16834BFE\
+FAA78B6A806D2E0D1B54451532B4F77365989259B8B48AC65C0B730951DE373B4D51276B\
+0D364BED18782613DB2057C4EE9AACB56CEB2D0857BAD4CEB9A190AF7B9E04B8267B:\
+EA42B4BBDAB135C2B0BC54A539D5C9A3D9B6EDF21C92763CC8F468BCA9CE5D2C:\
+013847F7E5082E4F5FD6DC16D754A80D
+
+A7033720AE2A602FDA4BA5127C4EE042858D0376774704D582986A848B2A0DBA6DF135CF\
+3F1E5D65F68E8940858A35E9C61E7AE2469CD7B08BE72069354A2A13955FA21FF3B4DBC2\
+712647AA20D73428D426F9B279B5A0C82E2A2620F836B28B03BDDEF45FF3366DD9AAE66E:\
+7FA21E16C5213010DB8F3DDBBDFE1E5AA16696875F632EDE3CB31B4325C4E2135B9D2C30\
+42CEB5415306D0FD7AE237F26E3F135732BDE6C753D0D844AB8270A094D5B24F6C753EE8\
+6455B2E936F2F5EC5AA4058099F6929C95AA2AA6CF70CB2C519D6854579CA23192AD83BC:\
+AB8512537C3519628BDABF83E005E8685A180AAC1988E48E39A95030BD4FA6AF:\
+693E3B87BEBD7D144FDFC1796922F843
+
+E84897FACE6ABD7B897B935DB435C22299FB4346BEE1C4381948622ECF3328172D0C3A48\
+A30EA2411201A5907778C994EBE29637A290EE6DD503B6EF1D53D368811D5DD731E7E44E\
+27EBB7382E6AD4C74F49FFB62CCF996FDC7710B943334284A38957EC822B4F448B7482CC\
+B972:\
+C5B740D2E9AE85FC5CFB4ECD1E375C05AD9E5040A8FBB149320C263150A83F2DDC3FBCDB\
+DAEE0BEB6C1CE6EBD3713DCA848F87200922C1879238E49DDCA5F931F1EA2CBC586402AE\
+B83F1BF2175341D4937CAA2B97F4BB51BDDA63C1F50686F2C40AACA7F1F049F08D43C6F8\
+7E06:\
+69BE0E539EE3C48F260249A10B2DCD3A63BBFBB5AFC85D9AF388B79240674A6B:\
+9A1C7753E6140825999B5695A2CAA7BF
+
+54D9C7F322D68ABB78ADA56EC4B23C1478DA181F30C32732C9ED38BBDCED81F063255395\
+C52E8EF6BCA23CD23A70BDE242DB86265C11777A13CBC9752F2ED55CF9D816C2F83AF85B\
+25001D486F5812E39F4F661044091E10C3429894E92EA4F87CC998E22ACBBF867D3B5B20\
+C97857C9:\
+1C4D79F2EABBF97E147FB8369933B4C7E7BA77C6A539F571AC2AA8E37C5D8BBAA1308DFB\
+BEB2F892BAE9064692A20B8A2CE2A1DD8879160C7E46E2E5039D5C32E50BDC961F3A7DBD\
+A36AD5043A87C9F0583EEAF9995994E764E19B62CA4410A87F33DEE40747EC23CE6E41F2\
+80858149:\
+B66821FAD6EA6320F3B5025EF909411DC68120198DB4B2A7BC148EA922F64DCC:\
+3A875E75096B58800EE21B31E39BF38B
+
+0EDFD9C739C9F72766EF8962032C1003669F5A648B0D21943E99DC5BF7A2507985223324\
+2187574B279FCFB57182F8F9832AA9E44D15ED2D8386AE4572986FBBE0E6E0D5D3AA4DEE\
+E2188614F7A8A381B335FCF9B899B86685320D457D85C9F761EAF43F49B9C9061AA606EC\
+A4750FE198D2:\
+87CB631FA8E039C050740F72698E74A93D758BF0D090B1993D6F7042E4E3A6360D0BDFE4\
+5EA8423B1C0FB9ECB9514769890BF994BE04E7A17874866FE1A15CB9C785B0A103F39384\
+A54AC746673A7A98D9F9E20D409F7E172592CE58EAAD74ECB2BB56C95C6CFAA6309887D8\
+956087009252:\
+33B871FD2A012F18E3914F1702AF7485BB793B7DA154804EAA715136B568BD6E:\
+596028337CAFA821457B88131F5E644A
+
+00FB363E56B460D690672DDFC0B71DF6E19F5A5E74E6E85E936937A054E8F7D87511FBEE\
+4A982792196FE8456A849AA1C2E8310E66D6C4BFFE084E791A5EDBFFCE270A4A50E5E238\
+2A18C3B9DDB1B71EF1E51B3568B75F423263E025D4E36012BD4350C226DC9805681D6F74\
+52591921AF631F6B:\
+33B7C9F0C16B82C6D6B08A42E1467592FC9F4D51DF70BFE52139614AAB3FDA3FDC97FA0A\
+235A2AF801134B58CD643E325A020AE796E333C9B3C3DF1208AA7CA5185B3FB1A7FC3B79\
+E717FE1A8B4AF71C96C2A58576CF14906E0CD7A8C4FADCDCF28145D26131DBD656ABF6BA\
+7D522FF9FF23AF29:\
+51D9223DE781C2931F7E2C08CBFE7FCE5CC2AEAE58D22819A60BD9D4A688C5DF:\
+0A55917388EC7A7648973240F8C2EEA4
+
+85F25B5F5D3E68479A0F84CB9F1D92DFFE17975C864C8A974AE1E2DE60292D281712952C\
+AF99C570CED2854B6C98BDF025DED8D8A873AEC8276AA9A1A6711C49FA842C4B446EA596\
+3994F33C74F7C9074B4576750770BD5E5BD9CFA01EC26440A122A6BA0E9A5E4B490581FA\
+BEDC940EAC9D6BE86524:\
+E4BDC3821AB65D06994979873EAEB03796A2A8F5B4507411F6E96EE5A246118EBCE8BD66\
+9514E234A991D708FF1704CB811ADDE53BAE3A147EDF0CAD867ED1547F4C4CF7199B35B8\
+C548D037E494E9DB52ADCDA17129563FB928D13F8EB153A4BA85F330F263FED7B14E66B0\
+C37CDA03133158D1A0FA:\
+FA54E69192980C674DC51DF702B94A43311661E98AAC776DD7F09FEEFF530B6F:\
+DEE6D2C5DB36158D964F28370B147CB5
+
+54E53C0739F2BA49B5A2080E324089051EBC24783771981AA4EBD0E63ACC86BDADCC32AE\
+88099729B4A72D8969D2EB1540F8A7FB3B79C5A0A7F769054EF2EFDDCE4BCA0294AD2B02\
+ECA48840A2A0AB20437D9085E905AA2074FC8C3561C564F1E992FBFB15877B7CB54DCDD2\
+7BECDDF9AB3A58699D4B901F:\
+6D4B53FC1B7FC8B97BA8E1D1526944490B415D3D59887437A24F8384CE850F8005512A8A\
+4BF1E79D03AC1245600DCC83EA21195835582B041B5AB2588DA8BD956D2FB69465485452\
+85C2DF36D26CD09B082F1CDB278F86FFB6FEF9DCC3C71E9CE6B629D7B2897B69CFFC2E14\
+510B4DEE8B9D957FC5AFA769:\
+D22A6E996F80C4AD83209F4E47A17D78EC0F1343CDA8890404FCA4103D038056:\
+3E4EDE2C0488BB09BC4ADFB3D1122E99
+
+2A365C1E10368C49339B3F64A7F25D6682E34A3BB273DEE16D6679B7DEA80FEFCE351964\
+587CB68A939B36D705A32F1760995CB3B9276BCB06AFF5F68CCAD25ABB7CC702D6DFEF85\
+722303C4D27BD81B2D42D2C6A47A9BC4706CEE256B5CF3110705753929B95248761234DB\
+E773C05E79EC9FF958DFB728F8B5:\
+75BD73BB09EE09FF5B8E138D84D776BB8D9B26274D42B012B1D252C22A0E29C66B2C6988\
+0EEDEB0F02376EFDE6F02C85ACDC24BF7AAB725D1CE86688ACB31C5C91DFFB290968B415\
+F7342AC9D60A49F7CFFD35D350D4B63DE597127C5614D609CA27EDD1CCD869D3C4554C30\
+81450A67A2495BAE987239937DED:\
+7B7E24D8792EAECBD7CDD6A43A1D0DB9681C8964D1A55332103C3ED167B2CAD7:\
+8EB77D48DE2CB3E862CBCD9D53234A46
+
+BB6817631F1F0A703F4D5896FF5C3CD94187A82F8287347B80924856B84CAAA3A05B892C\
+C8D8CAFA85F65DD1922F017728CE2E0ED7D4FC9CE844AC9FEFC79FE1EE7181939F4B7A91\
+213880D6B725FCB8348A4879641A628B7BEAB77673E4CAE70CDF36CC92D3784EF7D529E9\
+404C1E54A9086D0C33A50661295ABB24:\
+A2875C6E81960A33F8EC626B9E649747E956690DC4DE11801AE67EFD2B563695CC8C999C\
+1784FBEF30B753AF38C413E361D523C42521A4DA656BA0A1076E8773A335C854037DA8F6\
+E84EB48AAFBEDEF12D4451E9FF1636DBE938960753D3E0FE96165474298512792B8C457F\
+83A8664A4D679D06C22FAE43465F9549:\
+93C474796CFDA89D8FAC562ABFD5426E1611582D0FE40511A503119A48A07202:\
+81DB28BB02B082FE9F40675F752B9F7C
+
+AE29C830ED344F0072FCBDFEC9B9C634703819B24397D59C3D5418B47DD3861B5CCD2119\
+66B4DCB3FFC5E97F6B171F5C51D75B18AC13A78E2CDDEC9D4B23ED26CBCEAAE29FF78F01\
+C5B4201FCEBF7BC029C7730F7603EB456D2AFBD27581BD15941F85E816AA6EFB0D7408D8\
+5F83AF88AF157D3C90BC849031CB9B410819:\
+835993AD13882518F2A1662CA9B4160BEDC60E53083E1F8D72CA3AE2F890856E4B52832D\
+A83B341D9D992C0D9E489BB04C75149624C6D645BB9909E12711FC087C56E1210BEBA66B\
+DBCFC865520E4DEFAD4000CE0EC528916A415C4661E1ED7095E5777BF375DC31CED5F966\
+4C79CB3FB80C5EECC2067B4313CA27AF4F8E:\
+11C63D070095FCD408DC7E7596C177C0A09961B2BDCB6E7C0F300C918E7E830B:\
+41EF5DF5CF14D6D2C14CC4CBC4EADAB7
+
+BFDA49CDF67A114D29A7949CEE9BBDE5D26FF8E35407A266E12F98FE1247D74A1005366F\
+526F7460FF5B5C45D6791069BDF075C8BD396BA71AED8B7F812F0A31403046F30418A11D\
+B134127434B14CAF1E696DE716B41AFAC8FAC96687ABB8A81E1EB37C0C518806673A7395\
+AFED27408AF1B83B3EDB1D1AAF54B3C754E8361F:\
+D645EE5B89B1FDDE1056BFE827B8F7C2DBEB72E89E8ABA4AD0915193916EA8E6AD540288\
+69D0B1E71E396881006482C013B25915563C492B55F6CFF5DEA950590228899EDCA68C81\
+9B9AC2A485CF40023CBD4465170232F429D06DBB42E4E2C9B5E201EC41E4DF5C9674A1D3\
+2DD33A341E2E0D13351CAA4267BD869BB5AF2804:\
+BF4DBB8609E7AB12773DEB38FA1FB31DEF23A89137E4B292EB569028B6A5F836:\
+FE53D28C28A8CD12C0D66B79CE6EE6C1
+
+967DC68154B9B3957216DA8538588B899005DA3D2CB9500B1AB2FC4EE815232C01970F19\
+BF4068081EC07B041A6AC7A2FD97ABBB447C7AF73C0286EDCD99DBB6FDA189BA76212EC3\
+7B23A72FA8213D5C54AE716845E00262266400DC041D89AA69F1DE8B600F66B16485FFDB\
+5BFF89EA33625DADFB00DC35827C4CE73EB098B3A6639B26:\
+DAAC288ADD605085CBBC9867F0FBDD007472B15F34F8A7A91F16208CE15F0BD2DEF3FEF4\
+32DF84F66B1463777D3B2F0E3D2A41982BD845217383412BDDF2EB628EC8DF59240A32F9\
+FE442E334CA6670C6F3AFE7835C5D12E064F272C610F1084CE39380E029D050E5DC5676E\
+D7DD090FEF19A547EF90258670B3A49349728733E69CEC34:\
+B6E12C2EE1A50C4860591BC5AD7677BE5C77120BE31814A03B1B308198853950:\
+2E78B846599FB10E51D8AB906D7AC754
+
+6A3C46C05E280864DA7660DD5600F4050AF7EDE52B786F246C2BCAD03C8A88B6BBEDAC3D\
+5FE79AD40697BD88EEE4CEB3F0C8DF2F0F5381321D8C6E89049728B0A0DA9A71AF00DF1B\
+9BA71565C73F042CE22FFAD7B9DE33084BEE400C11E6A6F8398AC35E816E63B42AC23098\
+E7C5CA9B4D78395019B6123EA198EFB6A2E92793BBE243B46B1DC872:\
+2178CB3861AC4ECCA38D4C31EF1EAB6575AE0012BB4AEE9615069F62013B920F13797DB8\
+E432A8DC486F62A9F219FEFA356B8AEE7B1BFCAECE0DFA4F94E22A2219F6468C2D15A69D\
+11CF93B67AFBBB98F185807D32B794C6FA8F22794EE880084F6BCCD8CB5A7D0C59D0B737\
+781A60B29F17290D39422BE10A6AE430AD37C717D5C461EABDF8862C:\
+91E98D4A6EE9D7FD83D643C3BA829746FF2EFF77FCBFA41D44CE95C4CD76CAF6:\
+7B659AC1248FECCA3EE765ABB8D93D1F
+
+B0B0645AFA0E15A28D3EB6ABCAF31C6996CEE3C93B76F957424FA82B174BB3E9945F3969\
+094C0E6E5544D64606B54575CB6CD6E40964B84E94DE2193E7B9A00D4C5D140976DEDEE0\
+40585741F7ABB55CF8EE815F7848C4CD48D30C16783E76ECC14D384F480CE896532CF6F3\
+67E23633642794E6A913B871BDD702934E8968EBE1B2859CC62C01BE12091CFB:\
+406EB5C237784660784E9A1F477E4B8655B07FC54D1C69515C1B046005C05B82D8065886\
+39EB44323FCAA1F797D210FC51C91E3A51AE8236C0C2D6C521F2FAB29E89361BDA2275C5\
+43B54110AF60C7829D6C5CBC42BAEE86FDB0FF22C08EE59E81E63F0A98A6781926770B5A\
+C7792CCEA9847055813F065225B49F387E474A333D8B50926E3D7864035D75C6:\
+DBD7D9C318FECB268FF109238110F96FCBF2400BE054071478C7A2AFF75B384E:\
+BCDEBB1E6BC37F18D49C0A4A1C7665A5
+
+C47325105EFC7B78FF868A0E1CABEBB41B6A184780A52AA1D1E78A284C073089762B8029\
+9A628B3B22124250CC683CDB54DCE31E4072708C232129D437B89C0CB8BEC7A8F658291F\
+50AE9C66A0D62E26528032FBECD9B3112CCD022B7648BF995ABC46C57E821B3F3CE0EDA9\
+7358F31024F532C5D560D016CFD316A04FDD29588E6D50E681068EFDFB8361F93AA979F5:\
+D1043171968DF2B850257D7D14FBB7DE4E34FE62217E9972BDE0283E6EB2054874C6CB8F\
+B66A18A6F6885522D719EA965A0BE5F079370EB76587B8BBF5672FFD6B4390956C5B81E4\
+0AB21A15C8EF17D1189B6EF8E931A07B192ADDB3CEF0C66B28CF545774762CEC9968EC1C\
+06FCBA860BAEC78EE635495137D4E7B659100C59BD4496A850BC0FCF464531181F47EDAA:\
+B58E1583AFD26D09ECC1B81270BDA381ADCE90DA1A6096D27A61C8DAEDDD9F4E:\
+7BBB7496BA015237C080354FD061CBDA
+
+73DBE3EF41EA394F52138D24103977D8010166084F8FECFEA4C5327765735D5002FC7808\
+955D2DA9E786AC33F41A41E47D06E18B84344B4A5ADA2F925E536799ABE3367E0CB181EA\
+720EF44D286DF2223A34030E66FE161404724DB33DDB026FD5C88072D47AAE1BA89738DB\
+BE681D79E330856E4DDFCBD2E998E5065BBE6B3AB93DFFCC0EE04BBBB13E47080C511F74\
+61ECB802:\
+BCAA1E8F81FF49528EA23C4A62C40953CD98F16F91AE3EB6878C7DB5C3A6CAC4F8551A34\
+A5A624CC587A5A22E81CF9405E38913B77344DA59A53FA0BACFA1A4BBF64D234D1963AE5\
+E89159A24EB1237B93F25D652ECBB9EFD26E2881368287357D6783A8F3C1ACAB50FE60BE\
+7ABF7225F8AA0A06F54A63577634B9E930618A1CC8892D290ACD04F7933CF654A8A60AB9\
+00D8E0A1:\
+3A945A5C8FD52A46037A426C32946D59AA9B081C4993C634D9EAC2B7E144C040:\
+4C6D4D342E2582177F3641F777D337FC
+
+451FC9DCFBC3C8F106FC9C17A81D1C562E45341B4F05B5319C912CEBBE01743AE34D0693\
+0A5AAB36166780F9E75C154FBB1110375B271C297FC46D4B97BC70C1E8B378CB1E29F61B\
+5B0BCFBC8238E6D460054FEFB4A649430AAFDB7F01CF78A5406A3087E9C39FC2D60C4CAB\
+6CEE3DF6A3A8D2F0CD4134209C323D9CACF15308524519C40A81AFEC9736FF858D78927A\
+F66EFC5FCE806ECE:\
+C111527D486F8581AAB32257A7577B062AE1D781CF5B44333D12C3208BAF3C8E1276ACAB\
+0F4C325BC0D3FBF3913B13D2F06E8E64E2CF8017634AC9162EF32324A3465156613AFC57\
+779B9340CCCCBDEFC6476D2A4673DF123E435C6A98FBB8E59221C7667CB831EF2E7B5D49\
+26C9A022204F0B3564C66A9C8A7F494EBB337D148A8681982F70524C467D868BAABC86FD\
+50D5A2BC4C858342:\
+94EB2F6DAFC83A9FEEDF7081D40104F661916D4D68611AE3620A7E52D7C8F79A:\
+FCB50453BF443A452F735A2A7BFBC5D8
+
+5C1DB0ADA94F46127F18B21406B6FA32EFD090B0FDEB549474CFC19EBF68D4BFCB3137F5\
+47C48174E79DC87CBF308E0E9306E68B5FA1F9F67E005A2E033DF9034BE4F1E8C53C5D47\
+73846E8EA3782C70E8B1026965C40CDC7D5884F763BE3E2B64AA7458F48B6BC76818B52A\
+FB743300BED3971A416C587BDDC713A8C5782E91AD001E8D3DDD0EBDB978427173AFA9AC\
+A2180F7DEE47FA5A76F7989A:\
+C8E1CCDE12CBE92D8E61F23DAEBC35123564A94BAF6F2511B4BAF697D04EAE69C9B1C8D7\
+8E6383F9EB053C6B09F9A2A91EC0EC1CEE7801B3B01AF1E9BA4A481A4C7B73B0DC086285\
+C43CE33919DA440C1EF892D9A254FEB9179BAA1183EF319702EDB67FA2EE08F43A719D5A\
+EE5D3D7E10F0599278C70F25104885DA2F3CE797D3064FE6400366950661B6F703C8FB9E\
+1F773D893DCAC13DA94162CB:\
+E667049150AA0CC53BAB66F3EDFD5C32FBCBA264A6EB12D4563EB5E1E73F2D86:\
+EB8D65B2A91A7003E9CB84241B1DC009
+
+734BDE1B88BF91B571B7EF20524347DEA07BDFAEA8D194E00367A905DAB483F76F923087\
+B1E307EC990148E1C3B2E9DCDEF1694D9CEAE1A86A2D092D84B1247B5DD627B68E6CBEA1\
+7A539A5C650E8A6713ADDC2517B8FEEC7656264C795B1B0034B30B302DFBBEAAA12AA6C4\
+2BB3857A3C641A7A760C275F9C01521432A697984E12C2C7727A538834E90750D4FDF44D\
+F7083842090196A95D2E8143AAFF1D5E:\
+8289B871A4AE2E14F7398E510C5B522883893F59C8ABE42567FB879334A761E5332100EF\
+A7C6F6D4CEB8B6778D0C4B543BEA8B3EA58D198DC3FF02A8FB5CF063CB40E607087B5F08\
+DF86C906F14336ACB78832F20303533F8A7AE39A95C0AEBFA2985F97DB96E84EBB996F76\
+491D186ADC6D0C681F33F0FD3B42632E87E10DCEA36F222E4E7E8B4F2A5CF58D341BDA67\
+9516C829370C251824000BF463A75322:\
+F26DE261DCFE004B4F0B322D1CB4752F2D38279600B0A9421E1577C863A7978C:\
+2A4169C8E13B81AD96DC1CEC8723152A
+
+CCF6EDC92B1D17CC548C9973270FA54865DBEE4DD450683C7D542293BB2C59D2163027C2\
+29055943F7872D8CC2C9889B12E9B409D9EC55C346FE69998F013256A250FD23EC8C23E3\
+6B5412101FB35E7A0C78124BF23AD040327C608849E720EF644A552E35A2E98CB8ECC28F\
+FA8521BC4CD947E4BD24E4A70AE1A29572C746CDB98DE74477FF79101C9E75F45B55D6BC\
+2BD0FBC9CE24B569DBDC2DAB7FA88A07CF9BE2A0:\
+80FCDC8D13CDA4FD4653BE225654BD597279CE58C66A3CF67B95A8348DC976944477ADC2\
+0E9CD0E24C7913C928B2E0C531D43DD7F708FD4247D87954A7AFABE300085D169D280FCF\
+E16E580A0FF5AB435A7B64FAFE9928A11BDA14FD827D3B6DA14373879B4FF12F151BBEA4\
+17DB039CB8226AC91C8567B38DAE42015456FCBECE1C1CA8F0D2CAC3ED75F3D6F01D8F32\
+2F2822D2D4B0929D2831D9C0A801D49F77EEDA99:\
+32EA9D65FF14E80EB4AF36A9C6E8F663CB37CB6BFD131F14B49AB528614A613F:\
+3F1BFB148CB229C2E07719F6F99AAE22
+
+428D69DB8D1BADDB36EA5950FB2F99124A78BCBB0A7A9B1398F84A7E121637B48D12BBF8\
+5F045718C3F0409633E263F62F4992F4C6D497AD7093BC8BB1BE5663B40789DA824AC2EC\
+929C5FBB5107969688A9DB02BACFDB400ED395091A98DA4F806CBD7A9229AB96FB12BF50\
+2243D810B6A9B905C48B7612F94AA37E671F543FAD6BCD9C6B181506F447E90F88F050B2\
+C7B7199B88AE55AB922FB1BF4A5EAD00F71E83EEA2FC4F25:\
+5050237A09192DB1FABDE4EC7E865E3969AECB8900CAFD72B223A8E08A34AF993B1F3018\
+32DB0620BFC6757BEE80D215DA0D6B23666371158876E0422D540B2DF889C9F8EA92D181\
+A79AA8BDE50ED123C0301527C0987C4EC1FC105E6B8C0EC12750AC13FEE9CFF30E5A6DFE\
+47A6E63992A803F94D6E79F5693292C4D12D963BAAF42727FB9F6B144F6AFBD819C54D37\
+B3558EDEB4A049C7947E83E68C6ACE0203C882D9A038727D:\
+4A1EA133F919B366E3084F80E89E091C87F5F703FC9185F5C8E34E14973DCB2C:\
+CC96182632AD38AF5273863621B25E55
+
+C6092B37D8B6C14650D8AB31815C321B7923E9CAB069598003744F33EBEF1A693CC3E03E\
+B801BEE76182BBCE6CCAAFAA061250F5FC6BE6E07A3C39ED3F4344982E2DEC0A5075E5D2\
+A3218AD1C27F12C55D9BBC1B43BFBB79BAB35F74E1899517A839A54AD5274B8718F2AC2E\
+8F89A6CE94972A0AE020BE5256F8B5365B8AEBFEB63B886BAC9D263107A13B95E29A521D\
+3FBC7CCCD620E134D2D45082328AF1BAC6EB8B917B3F70A47B9D5CE5:\
+3F8FCC0A28C43035C055519FDBB13E8E5A4B35DDC04B62BD2AC7064BF7E4F7CA6C5194B4\
+0344F4C0D0C40AC3696C47A6CC2F800139EED2677E580BFF68399D8AA68DF7A28B95FA79\
+A1CD776739C1E2FB9C302EFB924013ED0FB2B06EB6B031FEC8AF7BB47E212859E1D13EA0\
+96E029EC051784317F63F5DFC2EB9C7E8E249BD88684537CC36785C54D8DA6F512450831\
+559BE2E67B024171A52F0481102C211DE9138120669D1C2A1F8BFB10:\
+C383B62616C48E3FCC6BB32DE3AFE5DC184E83ECB739AAEB94D82E942F0CFFCE:\
+52C109E1FAD94E490BD93584126E30A5
+
+0D85590B10C077184BA269C135DD1558CAD1A3D792BEDFEF45BCCE14E9099CC4B64D9864\
+97223B4D3CC9193E37E31FDE74E31023C9D265ED49E8D7B1032F1FA13F50E486F68FBFA3\
+B449F671878BCACA4009CF4607556E85878A2769472D481D30CE43787E1065BAC0506045\
+A26456644E7D5149C54C5C8387F5E23DBCC762E4369D4E7E24C4EB7AA5F3FAC3D76EEA37\
+DB6DE27601FBD37EB44D4C3F30E5688B549A029C22EE2282E408F9EBB259A86F:\
+B317F91E9BABF4361F26F96D001E3D63F3A82F2C8DADC4E4080611711CB4A7D77FC58D71\
+9B6ED93D118C7ED676A5B65CD259B9E1AA77AC2813B62FB869C42DBB0A710D1C986C0F97\
+8517DB2EA942D0F76C06AAD414ADE04BBC908DC428A18729B4D55CA600874EAF530B38FD\
+4318F1B2D97513BD3FF17949BAF9FFF3BB84C3F0065A521B4595E9801B5233DB2023D17F\
+5204D87AE7ABE1ED73F091A63CEB338FE9BDB2B82463E6B6B05883FFBC0AABCE:\
+357D3ED5C533FBDB195DD88811F3D6D50EC133A5E0A36DD256BC0E561ED28CF4:\
+38670C0DFF42CB73FDC3295694CFA934
+
+F8891DD530B83DD5EE3EF9050C7AA6A9C8A6EAAA4C8669FE126EC1C78A6F6583E57BEA88\
+84A368302C2D9C00D6F2D8DBBB98DC35152E43B1A9D744BF0FE1455A36B6164F09F55D4B\
+12290418E14A88F3F80A5EF558FF4EE01CA1ACE680FA028E81C12BF8A18A18792AE98513\
+636AB075C12320038C5BD733DCC8305551514D45E098E8E07EF0A293A489DA24BAB16973\
+D270E5D92AF34E6ADF9EBF945648192640BEE963281303D6DE6097E48D0AC4868E87A58D:\
+A54CF0CC7FF8A5B041A15C78F26EE7542BAC19254BD4D421E9A1843C66E9D8B136A80E28\
+31E6C52278CA54C79750CE64F6DAC5078BE3CAB44AE9F4D9019CBB310900282A6BD48313\
+7870CF8B0CDD002C61BBE679C2A87C7B1B1F1632DC57CC277FA4767D77BC2F0273879153\
+69012D0124BA8B2B85D8454499843C5F2FD9DBD584F9E2588BFDBA062C9F0761609BCE8E\
+0CF2B487F0F2C78A1C0B6D5C37D483F6B6EC52B7451B057C2D5FF2CD5F2BA443AFBA9215:\
+C2B6E94866DE53E7B7BF5827D5C0179A530094FE6AC5F44C9B3330D6C855E918:\
+A4EEEA6808FD5626B56AEB9206F86EF0
+
+1712A86BFE8C268C84902ED230BACA2B7B1610B5E6837ECB817D5D945E009BF627039587\
+D42EFB7C3966B9E84FA3A8A5363E1077F287150387C3A9AF1719D91CD175A97156049340\
+13A8A39A90EF97974A419796DB11DF04F3AC7AD348F37969FCB4F560B02108674026C17D\
+59D191A92DA7C7E32292D3DBCCB6D3B29C09F794851BBABDF7F455A9F050A069578B6A30\
+315BFA63448CF7A6AE2EC87C507E0A762A18ADD0BE18DF7BBD4F622B1BDCB693B53AB440\
+6E88AA7E:\
+3C43430F459A8E942D7360E97A89B2AD6454DAC2E72F64A1B06233810334C549D63D0BE1\
+C90A419203632CFB5C52E205756B751630DD08008BFFD348CD67C96774AF48C50AF4057B\
+4A3CCEB8DCC2223481AFC79FE717CEA8EFA2759C4B64339B2987175D14B4C195CB8E1363\
+D4F4249BB6F8A769454237FCCA5F848BFC05158F1D27BF39E1777A3A1648B555A72DA4CF\
+5B297DE904DCD84E36EE569B3F0E1F943873576F97D65B8669ADCA2BDB322E4A864DA4A9\
+E09BFE3C:\
+CD9057AF000AAF8EEF7F304A770DA1394F8707E59917A82671449D336167E456:\
+4DF89B713AC1141D62E2C824896B80CF
+
+EC9A99CC500450A9EDC1E707A9480144E242DF106E840B9E8D3DEA995A0C9F63FCC02117\
+02E8807EC1ABA88F5E33645B754B2E28EDA71F1B88E25B4B03B0909BD075F3855B4F6E18\
+AB07406AD94E9C32730C09CEF69F7A4FEB3F09C83D46338926ED795ED4EFBD2917E47873\
+FB6F516F6E4AEDA8D0310A914DAA25A08CE4528D67C3E1DECA8754552619027FA6FE7CD7\
+A1D9638EDB529445113C09FCA8BD4AA540EABB931B6BE201BA372D213162E14141E3AD51\
+AF9E684896D3566C:\
+A7A266F5E6CADE688097C04788CFD45BD87FC636201D0F484927B42FADEE8F789EF93F31\
+19D0DDE8E3716C3176360B928D3006A9F42BDC12D0591817DBD82D75FBA44C784FDF2D86\
+5E11215AF461C7DD1F9E3B82A146942CEFC56DFA4F8F80C4F0CAEFDD323607F43B33FBDA\
+7B6BEDF9DDB2A8C908E6D172900D2B4CC633C610812B62CDF225CBA62E09A8A1A1D7CBDE\
+1BF1C14CBF4C24080678677AE59166314703A11607C983C5AB3C7F755B220F10DB049983\
+C1EC0ACCB1368305:\
+B86E45AB9929C8382C8B068D619CD8450FAC18D39F31D38310BE8DFB8BABC18D:\
+3B10255473C571368D678D36964404C6
+
+02AD0113F276A03AE7A6C336B4DF4092F27AECFE4FE0DE526F6C548BBCA129FA24AAE385\
+0D0889FBB6F99324F7C01C749E5C7EA3F550594B98F4488F546C509CC256926174875DCB\
+99470F2D79EE7532E36A88BEAA0AB336197954B13171897727242BFE37DD15EE0F9BDEB5\
+E512A202AC3BC467C91191E83FAC86A80EEAFE0A8585E293558F7071C375A91824844347\
+5B57044ACA87243CDF11AA0838D9509A712626461E9DAFD0058A16DC7C4E8D69F53C165C\
+3CFD4AFAEC80E4F764DB4BE9:\
+7F3B26E6C98FACA940DE8DD01BF79AC15EBA4223AD8FF243909C321226B7497CCE5169E5\
+3A3A342FB1854C1802A38F87F393224EA8F518F633B04BB8EFB4ADDCD47CD2599249A40D\
+85A91CAC62ECE87834C028DD2F4FA50FAC1E6B591AEA8A454FE3BF3B41EF7C7FF533AD2A\
+5D4D690F899F5CCF8D4DF6D4FFF94E7F7567070B0309A905DC671515AA617018F7C37C13\
+763A445D48A5A4569D77815C1349A7E0BCB01D667EC0613A1EB0F12044DC748BFD1FFBF4\
+B173FE804CD0C91744302030:\
+CC207471BE9C6952378E60D263D69618DED46A78A21D8B7CA94E6BCBC4E3DEF1:\
+44F3D7AE3D2BA40BFBAA37A0709BEACB
+
+459C134A5BE569AFEBB4C7109D43FA4A5691B113D13CCBF47C06E90787A23C3F9C296B94\
+D47E2606B655C60C26E9DE647F4CC5BA5A49F5BCF458F40938E06BD259C20254F46F6932\
+C63C29EF311B63BE600E5BB7179FEA67EE10F7DA52C1A30E9EF1944D6321C3CE169123E2\
+E7D4B4074254D7C4998ED6C153BE0F79895CBE9B3462122BEA0FAE7B3FCCA09E5F980CB4\
+39A2F748D0E704C0184B56332921E85AAD4214EC7DA6EA8C6E852F7E1773A9602DF512C3\
+4895861E1C61D8EA0408F103E88702AD:\
+95042E5A21E494CF178601CE390B4F9AB388C698AB66ED4F2E7578A10984E30F63BED24E\
+BC839EA91BF852AB63AB170D8EAAF93FF2188D416DAFCF8C30B29455F70022284A6F934E\
+417F582B774B034ACC257C38C173556CC2909F5AF94C0E7E7CA69286CD7FC2C729DF2F6C\
+2543F4B12506DAA449CA990BFBAF39D386F36D490DE0932DFACA60644D7852007EA5532B\
+6EC98789F49E77239C236284FC94B77488FCB5EE37F0A3CF575541EE2F8FC0F2BFB67044\
+7A7E54C63AF122536C4B61B7A9C143F5:\
+DF3DE7C6FB886CE9DC51AEAC38374C29AC993630BEF81F21F725DFD4D6B799E2:\
+825A5B8F13472C46443D47145A1C136F
+
+158C45549636EE574B32800377F970320B9F861641425ED07021C9C4E44B5F1664046328\
+CCC1064397FCDB67015873B5EB433F52DF4936AB289A8CA161EC6A43E7459DC36332479C\
+704D956E18C86E11A8C1AABADD88E1EAA313A3D133004A34ADCF5E0F2301C3E0317834A6\
+A08CFEFD219DFB5F825CFA794DBA5971E6360DF22E3E0C15881021377DFD3EE69E53841E\
+F08B3F95D9D04CAA005ED15870B94557BB73CCE60B73495655C9C164098E2AFA19FA7420\
+6685D8103BFD9476808E38F8401FC582496A8EE5:\
+DF6250DDF592B446ED6D976462EEE2CB2D7830E67AB9567BC275CBA74CCCBBCF008441B7\
+B1593756DDAFAB05B1B728557F6D027A2A5EF2ABB072F456761AEECAA143795D93D6EC56\
+7D17F259013858513D20CB461BB51C3CD3D4204CBA768A5A3CD4B5D19563FADB62C4054C\
+9F7D8BCAF30F450F14AF29429E3E27C130FBC7B53840A00BACA0281A90293C6D60376B4C\
+6C455C771D1008A542E19B13AE1D4D14E3B8C69FB44550F74384C02861AF985BC210CF9C\
+4625012CEDA24B08842986E2DA30F9009113F0A8:\
+2DBCBA50DDC8EF3BFF1511BF0172A073CE37F42C83BA223D7573A82B13CFB813:\
+68A59DA89E8D3AEC1D4434F7A2EDD2AD
+
+F3087E4CCF4C82AA5B3CACFBFE367B2F501D1992D6455F10EA6C047A26ED06BF4393D53E\
+B0FD5B8B587B19ABE106269A74297B517D57D89D7CD26009B5DA7BD1B5CD40CB5B4DDA96\
+E495A02BF58108337A4F74E2A33C8EE14E730740F023560B70582EF4D1CE87C3AE5F5FE1\
+546F5C16683A0630342C319E2A5C43BBE7EE522BE44F955B4912A765B1AC476828C0C5E9\
+8948ABFC096ABCFC4FF2DD5077926C9A3F21F85D6B3EA941560A307BFB4714A11525C60E\
+4D70DCCA56ACF6FD3B95560CB6C3DE1342D8FF18828783C5:\
+996FC92E3A276EDF16CA8850CF8C9530364D170EFA51D1C5DFC2843A968E3CD1EFC50402\
+7C2E056AEB2E7AA5DC3EBED6CD25728812CEB545ED9FA552B1D0B1FCEFC4CDA5BC2646BC\
+5FAAA4C20B821A417980572112F737A7DDC93C39B533E9808D86A495547078087A678570\
+1D27D4632EA57D398F217BC191A30807999BDC509AC74AF3DEF4B1105FB8B904DD9F2CB4\
+158ED207614A07FC8F3803DC5BF81CAF15B709B099AC4F1F0968B7577A81819858D20967\
+77346AFC426792B9581202DDB4F1EB17EFFD81CDA476AF26:\
+B09FB55A95EDF75A610A03183D05A8D03D6CD9CCA7276530A72F6948CC074848:\
+0866EC523C35B5D03269F4F2FB004AE9
+
+710647FB3C699E7E83D1601D49513706C54CADC3034E47F8C20E1523225BED6FAF93308A\
+653921AB1043732F142196A32329AB98094C580657617967787D738A4EEF541ADCAADE48\
+84113C020026F6AF952FAEB1F9745B6D450FC86A04A9C4D81F4AB15089DC0BF7B1548D4F\
+850CFD97C6732FEE47B2320A31BEFDA8398C4AB0D7FC123C43F642CE07AB8DFE87B114B2\
+28455479AF224BF82B04BC3341D257F4EC166D9CBDB1793946FC2BC08B72F7099128CB41\
+0140DF4FA38A2EA4A2569DDE2E3AFB3164DD2F9D830A831A323A09D1:\
+EE6EFF319198C6C10DDF6F10546A5F38490A9D9858E021F5DFDFAA8ACBBEF0A446358928\
+5E8F1EFA697D08ED42F9160C4E6EEAE1F15D78207FB207565B9DE9DFFCDD96E88766B2BD\
+A996CBD439E45578596D91E88F7706A94C9428CBCC3108E1F61CBAEB184C30E5BA0370E5\
+DEB1A9B8A42191BAA3D722CEB9DF9ADB69764820FA95BE1B48493BDA88030469CFD41F5F\
+13731A983FDC9B2CFE562881BC479253A126D57A8BD02BCEF2FC6DD8BF1AB265C924EA40\
+F5CF75F4E36EE10133923E2427E19BADB34F221CDF4673D871ACAD8B:\
+F6286D8D4FD9D8B373C7ACAACC517DD041E6E8A69578CD444B22579B4D3C3EBE:\
+621D087684EF405E7E49478F145FBD45
+
+707ED22B1DE93A11A851C0B14B1CC4B09E6431FAF7F11E97730D1E9F5C729D9DF12E4DFA\
+53E88A5F8507FAD0AB721510E02EEBDB84EF9B34120FFA1FD80C5C0C3503AD02AF96E4F4\
+66C462C3B4F3D26C78DF8C08A551DC39AAAF7EE05B13D2E1B80DA5A1A532B13EF0D1B065\
+9D2A0B43246E52CF8B6CF4EC5918769C21C51C6D1DA8DCCD2F3B0360248480C36D4F5CB8\
+317973D42FF7DE23D34329FD57B204EDD045BB87DFA5913819F15C6D5049DF1DBCC696D2\
+4C34160249CD84AE0E94C9D50A5EC764C48B26C7C8E28BBBF418525F9FEB0DE1:\
+4F9221B68E45395D5C923C4A6F96826018E207CEECC5DF1560A7587D15427B75FF3188E2\
+19D5EA5F92F909B129D6CDA2AAFD9D52B8B0C05B9E9363E8117E9996923ED6C59287108D\
+A2F5FF3451823362B2CEAB17E862E622437A990F7B23A9FDB6791A9FBFC1C06214673C92\
+41164044EFCC6439AE42079D3B1130320A878581D2EBD264D4FB53ADF5A60091695636F3\
+EB58B73A3342D3CDF833F7E82D6EE1FAF65E327DBE4350307CBD631042517C448F91603F\
+2BD6038FBB847B53F98A8DF30205022C613365C8C69CC55C6B911CF3D5567004:\
+6886D97D7FB73175DA93375F14FBA49AAA7ABE901751EB42CD243B568AD6DC18:\
+9F9E1F292C86CFB45E0334700755C190
+
+0612DA958E54589E58F7C2E70F374D0CC47109B326598E46FCFD23553E3D84C703475618\
+68DD38847E0096E2FDD36CE8997820679ECD5219FA16CC9FF0F2DF8AACF9116E6FC9F926\
+1674EAAC3142DE0B9941DE77172FCA477759531B77348D914017B5E1896DD87B3DC0CB84\
+4CF642C1919D25E21E2A94977065621A4433265F590DE23612FA6B16B031F6DB3648A42F\
+57DB126211F6FE7231849B5B54694DD736E512D1EEF0001BDD94DA84AF47C71FF61F4951\
+019CBFFAB709278DBCB60F17EBAFA7DDFC071ADB89EDD569CF4A8C7D566FF1B7E20CB0CE:\
+67943CFCC4B795A311DCDACCFDBE44FA84FAFD87889892F0410166017B032B78CE7B96D0\
+3D00222424E0D363DD321634F4D151E1E03C357BEE8AFC7C561E8629EC55EB52567EFC8D\
+906C2AF0E4C385A0011CCB9E254834E55F7870F10BB563BF0A732CD6AC6F8DDF19C0D3E9\
+AF3A7F54C38E66BBDF3CF7A00361FEC2F5A7EBEA03C4C42AAA0A74F11EC51D3F5E1F78B9\
+0B09CB524F7A5DC8CD561E15EB866449F4893FD49346290A63A8D478A0C5ACED66550BF6\
+4D2A0CC5AE29886DA6DF798D8EDA7258B74BECD3094D6E83A61A9288EA1A8D0FA91E6F19:\
+F1F03359760DEFBA1ED11309F0C1D27A311FA4DEC398107B2D0AB2E0EAA895D2:\
+2FF7028F78B7F5623CBE7D592EE5603A
+
+4202E5DAF05E4E2DA055A9B76CA4C678A5D7F1B5F130E68389A57A52AD82B1A08FD35CD6\
+1832A0964A5C66F91E9F7826DEA9C78F5257206DD3A78C099768524D1E3B01306A9AF70F\
+2FA7DFB02F9717C2C9D7CF037603B96AFB5B9A5C832FFD86793C0228F9F38593338D92FB\
+70CFE3EB0B4B0E149E52ECD784E0756C1934B3DE03B439292052C21B40CB5D39FDD7BF3D\
+81C314F927C6EF03FB4270BD1DFB796EF59F887AB566D2AC112C1EBBE1C98679D7F0B724\
+94BAA6735FBA58D3CD125ED42272E34A9D51407D5550FD3DBE0E06004D31CA3B5CC1874E\
+10A60668:\
+DB896F08DC3DD1224CAA35F8D841E6174E03595794F8C623987CD275AAFD213A0622D2CA\
+B9DA6C8FB847FAD852352CE37806529A4F06A1620AB065D157E8992981BC74DAAE1AAD30\
+0447E720146174D75C8C09F1A47D307C6492D93E7035A081D4B47EAA116BA2F2643CDF4B\
+26EE8B82BC90FAAE8BEDC463B93F2ABE99BB7A1FECFF8FBAADF907FDDC34AFE59484DFEA\
+97937C02EDECBD1F3827518F3183FAEE67798726A220624A7C5AFBCDCABA3ACCA8862B31\
+9DE90F4C59C13EF1B8FF43DDACBC0A18548F148676034A3D71E928B1D25609C539C3203B\
+7055498D:\
+8739533FF38CD3C2A5969CDF010BE33299B5772DA0F4A56FEFBCFB4C187A398B:\
+C28792697951BA0551162D5FAC70775D
+
+2A797C4F230EBA8E8D560B141D6F7498036F7C54D326F67E8A0894E7C7DEBB49A717E2FF\
+12E5020B8F4F3D00236075334BC1C1BE18609339FFE59A60DBCCA006446B05FF8C296E57\
+FCABA4121656638EB88214BB0252941598EAEE42966CC162D78D0DA6D54C037876AE0931\
+F94BA160CD17DE6FAFFACAA68C5F765CE64BC85B4B132366618C723B04ACBE5392991A1D\
+1570BB5D3FF257256473297D9DE7FA8901F69B8603C9BBC267E3629A33A6A79697CE70B9\
+37E6B15BC6DEE6C0298CEB375B40DB4E0FCEAF71D5302680DE2875F14750E45771D5538A\
+CA54A19EE9E438CB:\
+B0C2C84FA758C6144BC07E436E7C4A7FD9279C35256524329930F5934B6D7CF4BCE3C7ED\
+4D6603794393D85C28E4DB61D4FCD17A90EE2AA4E6C29E99FD6C4BE9E245329D4F33127F\
+05C903EE1360DC713132281D67D23BA2B738A0F8C66A071DD9C31A19E13489EB8681CA99\
+84B3020F497CC66E5CBB3979F09B0A7C5A043150D846EFE148E7871A45FA8DAC26416BE6\
+936E5D3289A5B7AB77762726F7E4EA82D00D3123183BAF7CC146C761A7FC483055C0D687\
+944BCF9072377A7F797EF2163FE07B7656A56083E351EF3F2026B19FF76C3162CAB2CC86\
+293C537407F0F569:\
+C7B7849FE8962C5670F745C8E26B979CCA21F1628305A75E9372A684EB8FAB87:\
+CE0C1E9870A5D615C9F6D8826D7B61A5
+
+43328C5C5E30B0396CBCFC0E6BE81C49B9164FBCB9A9081CC22E223CA5CC5FD28922013E\
+4A9A95DEB0025DD15087D516FF4771182A67E2E69E55C19809A8B9BF4F77E02748DB3CD1\
+CC0718E37C0A9555E703C579F5761EE6DDC484BF619243A95BA97E8B0A5CE152F3C1D72F\
+D69519E9479F4B1C46C23194DD06050224A7C2F467BE08C7EFCB0AF1DF523E294FD7382F\
+4B60690CF7EE8B8AEC379363FF636111AD4CFEA81EF2953BF76C2C8E76DE5B29334FCD09\
+F01FD4902C1021C93BA381CEEE9ADC7CA08D18B00FB5E652839848999FABD577870DAD51\
+0E8115B01AFABDD683FB3CA1:\
+1775067911F026BEE6DAC1CB54B8FCD1AFEAAA98D610FE00C63524F9AB0EFFE7CB7861E1\
+C7B1243990514BFD92C1402305958731E5E730D2AC179916220291A604B479471A249874\
+D1B067558F0D61F29790DC82765A0C4B00DBC0AE2A3B1E608E9D1F429E64CEB08D2AC7E6\
+1DC0A3B8174D8F79CA27260991CBD7D739128012B6DF93DAD582B96603E61398BA8BEEDE\
+F70AF98CE871CB49F2557C239CD61BADE4F38E0CBE1EBDC4580B56CB1830B5A14179C55B\
+A1C3EBD60F60388B164CA51F1369900E9C3FFFDB39D0E9A594A329723CE60A21E7C87F8D\
+756EE5C92CBD45D7E5A57395:\
+BCCCB7F12DE82B841EF1C0171472BE0188C2468C8D660F268F2332530A2930DA:\
+570030C34B809C5D361636F477FA84CA
+
+033362424F88682DB69F71DFFB5C08A010BA4394CE1305A467B4BC7E6DFF93DFBBBD7FAB\
+DBE62567612AC8AC5581A7A506D13CB8FED0C856A89D84B4D14D98005C74616704E46CFF\
+43A878B66D1D6B3636949C19404EC55B61A1F5DBBC829AA720FB4A5D3FDB8919885E6CCC\
+35943AC13E655E4149A587C4A60DC54BEE8C64A0DF49656CD4F67FD5ABFE1A8090E48212\
+646D730B50E8255774A3A1756F63DDFBB33DC0D2EF5786B6BB6E303006A2FA3217143CD9\
+237D15F24FF27DF41A9099E53432EBCFBEAA0ECD5FD419D736857E57F8917DAB5C20274B\
+F0F61075BE07EC5383BDF320C8F04FE4:\
+11C73FFB2F85FE26E087184A4E7D0E74CA4769A072EC036EAAA0162984CBF53979926FC7\
+09BB59158685C6F131BB3E79886D13F0A644A420D14DE9DD497FBBF5C8CAF27E6C2CFD83\
+CFE6A5219EEB8B29DB9D2722FD7E1004BD1152F6698C4DADEC589BBBFA3EF96BCF4E90CB\
+1395EABA2F1D90D5B2F81F312F2AF94583B4F3A8DEF1EAB26FC8EC9C4C2663F4CBF856B1\
+BA593A3E3F54B3D3831E24B44C7A5217695F3FD36D834DF32488DF461A118A93264B2E66\
+57DDC66D246720E94EACD77ECF23642A036229143868ABD20F3B1FAE1B852C9669CCB0B3\
+334FBA0D8FEAFDD56D03E52F5D136E87:\
+2CFCC0880B1BCB48651602B2F653034A6B8406B143AED550F85F122DA3BC6E28:\
+68A553188B539B46214ADE17802A5ADB
+
+9481ACE7C47FEC3A22B41B81E1A72363D4F4EED3CB0C93200769415B4779755982EA26E0\
+F6363C973A7C59A43FD6CC4B2D1857EB38B5AE5BEA22DA4781AC36F5559A2A2A8EC111AC\
+33275AEB3863B2A7CAEF572A16523A1231FACDF0FEBAF9305B658A4E7B0CCB9A424D5838\
+4B385132389D5545ED6D2BDC3D615D229ACFBCE60205CE1119322C642F4D81ADAEA50995\
+E4DEEB23D9976A1FF4A9C8CE7F0CC7DE657690F9651E53DE4E58561E9570CC4526FE03DD\
+686BA1AF9557718D38641B080592C9BFB2FEAEE56AFACB4F811439FE29AD6BA8D6F0ACC3\
+FE3836369CE06AEAC64898DB676EA7640D7A7BE6:\
+8217EAB21AA0D8A541AB0CE258E96EDD82866A5460455B82C339F5157C2B159FD8CA8AF0\
+413BDB5995EBEE6AB6E1F8FBB03C67B086DD2E6AE05E0B37ECB43EC2C77E9510F24BA1D6\
+E5D4906A10BEDEC2D3ABC09019274E8D09CD3921B3DF7F9EA607011655C684C3FD435747\
+6F97C1FE8314A80AE372EC4C4B19B5D34469E66A94DDF0E0C5546A290FE42A3D00F071B5\
+846DDF4D88E320E4AFF2CE3D650DDCE965C16C3943F1EA5A63D9696F8DCA6D7D65C3FAA6\
+157549B214FC3B44E6C62D124EA327E97A91126256CC475A5C533CAF2EB3F6B08769436E\
+CCD52D2AB31A87E1E09D00D2F835BF9A7356EF71:\
+30A6450164DA25B43CA6DB430F827299AB79CA4A52C636C690F7BBDF82BA9B0E:\
+4A87D1FFB56ADFC374C09B2F8D021CE8
+
+3F5E7DEA03EC52DD0CDB0030F676EDF2EC5B91C788D1AC9F8E88391FED510CC64123E47A\
+C2B685E5387365DC98DA305A832BE09C50F2E3E5B97E02C92F92EFCE59DD0A18E1227661\
+719B54397B0367359A1EE476E8106D2CAF3988E95BCA0947E2411574E3E61D79BC8C6FF5\
+F7D806BDA98E0C69E4F44F70E9B2F1178DA75DB504D3F8096AE002E2C7C36E95EA3D37CA\
+3807E760424D022697FD763B1B85E4D4D15D95153BFA3F74BADF46EC1906B1904D250E98\
+4D7CB5314EADD248A801373FBE2D9EF1B9D82AB3FB0C2CA0F3F9EC0F83268EB2464E40E0\
+C40EEEFC1B9C4859A357CC62C5537783D7437E6509689C6A:\
+E4E2000ACFA0762A90E16CE545060CB60961F69586A8845D37709DA643894EB7BB29B2A0\
+69E0533EABEA770AAEF101CEC381983F59278E7EF2A55B190F7B758DD97050315B3EF563\
+CF92CF9D2CF955F266C77AC4AC8BD7BBE39CD4F5EE6E57854C8F2DDC6462889E1F02DF8A\
+7C1AC02B65423A17299973745C7C4F17E4579F514F199932D98062E3F0E141A8133CD974\
+A4B1C8A066C4800CDDE54424F4BE19C4E0099A9AAF11692C27E182AA55DEF8A439A746E9\
+DDB83F674F76F297BBE8C1DD7F4A4582260DB38C14E6FC40FB1DD429FAD55769A89BCCF0\
+0677FBE04B07C5BF6380AC4DCF47FFE08AB15370ACF4082A:\
+9361EA127351940052051851106E32E21B5B74CAC5EE2C65A478DC07962653D1:\
+F6159606256712C7DCBB2F3E8ECEE258
+
+378FB5CB6B0FAD01796C73A850C8EF78AF71CB2AAC0CF7FE9EDB58D64EFA6D138FB8FF48\
+4500C5E15F8013ED56BADC846334DB7AA6DD1B0C55BCD1A32B93A86B54B74D06F3224369\
+D5E2ABF310A13D76CD3C0E037E161047CCDB49C1F117097AB42E0CEEFB4B09EA86305C72\
+D1627D53C5D8DB79070F20BADF51DAC0F6D019C7520DF841978F0249E24F995D4C0823A5\
+CA663B67B25EEBB8A38A95D27F44E425DE53CF55E5E3811CADDB9C0AD3C415587DB968FB\
+1F2D93D3B02D5628BE64E09AAA0A79E9EB6B72D0088554E77574315F1152F489ECCC4B8B\
+9705B10C96CDF2368DD61D8A345570B4751DB4533643C8F10CA2E5E9:\
+6EC13D2297C89EBE84380FD858E68FEC5E09BA9F4974C03B0C1A098C42644170358B7926\
+01D88B40CDF56ABD6A2D8B7CA430AF87EC349C2B11D44731A0C219F0DF310832ECA798BE\
+E87C293C8834CD74724E96A6D7A1DFCEFA893DA180CC2CA8465274D176BB0D25B1FCD04A\
+3142EDE3B74A6D3E1ED86F3289DED1E37D32B9925C8BB51913B2850E5DA43159D4F70F64\
+06F5BCF600B1AFB2244BFEED3B40303C58892BA8A59151F8E2649964E767D918771E2681\
+26CE88156C4FA319F65CB1E2909F5A196399B45EF0B040C3DCA7E79232E4782041C7E6B6\
+5C9C82D8B4517B469493A46831B9E9094AEC31639E353F40D3AF1488:\
+2377222F39987D62CE8CB5F64E88437543E20EBB58F2DCB159E0AECAF439217D:\
+2DAD0FE823C71638F1910AB8D8924C87
+
+41E99B44C7C94FD5B8978507A99DFCF6EC7A49304EC6099AD1C38DBF8BE918860AB5C37B\
+D13253B763406AA6DA1CE6779CED6F7F7B222CD51967BD3B61FA48F6B65B96891E34FB58\
+3E0935454ADCB3CF6419216B798A7C0CE5402A3232510940839D4DCA082247505CD68D73\
+B1AE4E352B9A95F6CD68CACF68F28A525CC3DAA1504DE85B51CFDC3B693DFAD28D4ED86B\
+70B93B02FAAA0BFE452544C81ADEEF99A59378CE0625234EA69E9F69ED52D5FBB6687F9E\
+E248479E1B29ACF0CC3BE7BA5B77537C29CAB662B2DD7D8937B9DEE577E7C8DE85D3CEF3\
+0912FF62687756C6F978FBB147E6B27E923C62F9A38BD7F50D8801E676FA07DA:\
+BC7838EBF0287786D89BAAEBA8ECA378E898BB36A6D3D6CC125938D71768BA704E30F9FB\
+7B09A43D85786790FCEEBB46A2A341C4EA50AEEFF3DC57005DFD7BE9C4052AB3CAB38B11\
+221EA39EA778AC6F4111CD1978E5D467301BC7ADDC54D084F36652A9AD3EDB8D70AE6380\
+3B077A39CF064017DC2A8CED0E4B1A7D6FAB58B0FC92684778B7B3F5D76477CAB7C6C1C6\
+AE6BCA1F661CF26DFEFCD1DB5DF58F1358D38406E3D880F30E43E1837132B5DEE65EC09B\
+7622CDA1F52A78F8EDF870D2AF375C7526C70E43FF650B8EDCF6A35D02CA479DD560A672\
+45C7087D0376C9915777FCCB390109115AAE52C4512ADAC046C8C1E9092F3018:\
+19F394E4AF235F4BDD3F0798E904A2E114041B351F0D71C5BB269845BB53D4B9:\
+093E57768A6107B8D6F31A083B23B3FE
+
+20143BDD828F687A93266C2E489909BFD6D85884A40018082FDE227841647D162DAFC241\
+40580495B6E0C393CFE2BBE80615C87CBF5E057D74A4CD7589DE69E136870A24AE67F9F0\
+FC7B92369903718B9268500155ABBD6C8D0E81FB1104403A02A56FC82F1DE4137EBA1433\
+AAD9CE7B34198ABE7D9845DC462DBB4FC6DA4F937EBEAC139339B405ABA51BFC9B06B38C\
+BF17352F47C6EF3968F06305123888130738B887911567A28DEFBCE943D18C73ACBE920C\
+386143E0B6B2C9EA30C84A7E4196481F93395C8BECE5F9B341725DA7883DD74792AD0140\
+7A05BE7A2121AFB2E9EAEBBA7574F9582D0455571A077603A511ABBEF9EABEF4553A48EF:\
+FC293D577FE018127C31A901490F19DD72D0A3212C828EA530B256E563874E03C7003668\
+84568B2F58B0478B8953F5A667E070BDC386404C47A45A862626D7F621C5E87C3F48A15B\
+8F7DFA5EC168ACBEE32E08551DC7AB5826F42A75CE8A0A61BB9E1F4AD5BE53AC87687961\
+388BB809ECEFDDD93782A956F9976242B20B1C2B5EAE31D28B48A44337AC677C6B865D89\
+954E1159353FCFA1741C287FEE15473CB4004E400FAF336995004964A79E2EB0FDF48C2E\
+A09120126443E8771F9700718BC94E5070DA8DAC17BB3F73555F3942AAC1C2830371D641\
+7EE51EBCB1ACB8B4C74BAAE38E6CED7F7622388FBE2B2153DB6945B77AADCF7DC99502D6:\
+BA516D7A4B7638995562CE54FEFC84B6DFB4B8A81A03F24BB065B060E4FA2966:\
+23C93FBB6EF742A576769819A5BC6AC3
+
# MARKER: Cipher Modes (Decryption)
# Cipher mode format is plaintext:ciphertext:key:iv
@@ -24360,6 +25419,37 @@ E5C7CDDE872BF27C43E934008C389C0F683788499A7C05F662C16A27E4FCF277:\
4E6F77206973207468652074696D6520666F7220616C6C20:\
0123456789ABCDEF:1234567890ABCDEF
+[Serpent/ECB/NoPadding]
+B2288B968AE8B08648D1CE9606FD992D717EB02EB81A2E939D54ACA91087112D\
+0D809C5EE82F477EBA7B956DBB23463B0F0190D616F5294112FFB7884E8B37F9\
+41BA1B505386B7428B88338188F7E718A3348230BF5CFA552F88D22463D9703A\
+115351622E016BCA26918D17E13225F67EE4E3F2C46FE52ECBDA044C585717DC\
+563A8403FF5309D62370B1DCF5A11EDD2F7D73602B70CD2553E44C1D3F170126\
+155BBD9BE3A965B345E834718F651CEF6CC65E8C5C566E894817350F497816F1\
+EEFA51FC91FEBB6E9F8CB141CC0EB6AF3C6F8380CBD3C996167F2F0E90E71B75\
+6C87EB62A4975356B28DCBF6A64A0BD107206D48FE6DBE19D50314B90AC87B83\
+35706F9B26007071AD8105CFAA1C1E2FF7FEAE5CEC4D11477F24E6B200906870\
+3C0E29E2950F2AC2DACD63DEEB5C7EFA9FDB9F3B740563D5518287DC981FC9CB\
+46D4B5A5A86FEC08FE70D18297DCF51072DDBE038DA040EBB12C509F5940A212\
+DDEB59F02132BE4581FC23EABAA960D6341D9352E36DFD6E4EAF0F6F439BC8CE\
+73A9AB3164FF30350F2DC08E939A104D6DF0C2C28F8E2D44468A61278BB6B429\
+4DAE45AE0CAA032FC97CD4D8C57FB83BBA8AFCAE22070BC882D3A42B38A09E65:\
+D29D576FCEA3A3A7ED9099F29273D78E2D62A890CEA3A3A7ED9099F29273D78E\
+D29D576F315C5C58ED9099F29273D78E2D62A890315C5C58ED9099F29273D78E\
+D29D576FCEA3A3A7126F660D9273D78E2D62A890CEA3A3A7126F660D9273D78E\
+D29D576F315C5C58126F660D9273D78E2D62A890315C5C58126F660D9273D78E\
+D29D576FCEA3A3A7ED9099F26D8C28712D62A890CEA3A3A7ED9099F26D8C2871\
+D29D576F315C5C58ED9099F26D8C28712D62A890315C5C58ED9099F26D8C2871\
+D29D576FCEA3A3A7126F660D6D8C28712D62A890CEA3A3A7126F660D6D8C2871\
+D29D576F315C5C58126F660D6D8C28712D62A890315C5C58126F660D6D8C2871\
+AA26D561F567520E8AE47528C24C18D731A2193D9A97FED6922B17AAA6372B74\
+BE5DEBD559E303C9C92B174A5107BBFEB626D8F65EDCCDF3AEE475C8A1837722\
+41DDE7C1F1631F5FDED4F42746471BD651D238BA86176EFE39E4695AAEB73B52\
+EA5926CADAD8018962E469BA920CB8BF1EA9062E4D9CEDD5FAD4F4C7990367A4\
+B966E5C5D2277288C61B96A559CC84AFB6A6583C5AACFCD6212B0BD8AEF3C6A9\
+A11DDBD175639341052B0B384678D8D9352299B71DD880E29D1B96452DB86540:\
+00000000000000000000000000000000
+
[RC5(8)/CBC/PKCS7]
7875DBF6738C64788F34C3C681C99695:FFFFFFFFFFFFFFFF:0102030405:0000000000000000
7875DBF6738C64787CB3F1DF34F948117FD1A023A5BBA217:\
diff --git a/configure.py b/configure.py
index 821092151..97fd44816 100755
--- a/configure.py
+++ b/configure.py
@@ -9,6 +9,8 @@ Tested with
CPython 2.4, 2.5, 2.6 - OK
Jython 2.5 - Target detection does not work (use --os and --cpu)
+ CPython 2.3 and earlier are not supported
+
Has not been tested with IronPython or PyPy
"""
@@ -34,10 +36,10 @@ class BuildConfigurationInformation(object):
Version information
"""
version_major = 1
- version_minor = 8
- version_patch = 5
- version_so_patch = 5
- version_suffix = '-rc1'
+ version_minor = 9
+ version_patch = 0
+ version_so_patch = 0
+ version_suffix = '-pre'
version_string = '%d.%d.%d%s' % (
version_major, version_minor, version_patch, version_suffix)
@@ -113,6 +115,15 @@ def process_command_line(args):
target_group.add_option('--with-endian', metavar='ORDER', default=None,
help='override guess of CPU byte order')
+ target_group.add_option('--with-unaligned-mem',
+ dest='unaligned_mem', action='store_true',
+ default=None,
+ help='enable unaligned memory accesses')
+
+ target_group.add_option('--without-unaligned-mem',
+ dest='unaligned_mem', action='store_false',
+ help=SUPPRESS_HELP)
+
build_group = OptionGroup(parser, 'Build options')
build_group.add_option('--enable-shared', dest='build_shared_lib',
@@ -162,6 +173,8 @@ def process_command_line(args):
mods_group.add_option('--disable-modules', dest='disabled_modules',
metavar='MODS', action='append', default=[],
help='disable specific modules')
+ mods_group.add_option('--no-autoload', action='store_true', default=False,
+ help='disable automatic loading')
for mod in ['openssl', 'gnump', 'bzip2', 'zlib']:
@@ -400,18 +413,27 @@ class ArchInfo(object):
self.submodel_aliases.items(),
key = lambda k: len(k[0]), reverse = True)
- def defines(self, target_submodel, with_endian):
+ def defines(self, target_submodel, with_endian, unaligned_ok):
macros = ['TARGET_ARCH_IS_%s' % (self.basename.upper())]
+ def form_cpu_macro(cpu_name):
+ return cpu_name.upper().replace('.', '').replace('-', '_')
+
if self.basename != target_submodel:
- macros.append('TARGET_CPU_IS_%s' % (target_submodel.upper()))
+ macros.append('TARGET_CPU_IS_%s' % (
+ form_cpu_macro(target_submodel)))
if with_endian:
macros.append('TARGET_CPU_IS_%s_ENDIAN' % (with_endian.upper()))
elif self.endian != None:
macros.append('TARGET_CPU_IS_%s_ENDIAN' % (self.endian.upper()))
- macros.append('TARGET_UNALIGNED_LOADSTORE_OK %d' % (self.unaligned_ok))
+ if unaligned_ok is None:
+ unaligned_ok = self.unaligned_ok
+
+ if unaligned_ok:
+ logging.info('Assuming unaligned memory access works on this CPU')
+ macros.append('TARGET_UNALIGNED_LOADSTORE_OK %d' % (unaligned_ok))
return macros
@@ -717,7 +739,8 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
cc.defines(options.with_tr1)),
'target_cpu_defines': make_cpp_macros(
- arch.defines(options.cpu, options.with_endian)),
+ arch.defines(options.cpu, options.with_endian,
+ options.unaligned_mem)),
'include_files': makefile_list(build_config.headers),
@@ -748,9 +771,11 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
'static_suffix': osinfo.static_suffix,
'so_suffix': osinfo.so_suffix,
- 'botan_config': prefix_with_build_dir('botan-config'),
+ 'botan_config': prefix_with_build_dir(
+ os.path.join(build_config.build_dir, 'botan-config')),
'botan_pkgconfig': prefix_with_build_dir(
- build_config.pkg_config_file()),
+ os.path.join(build_config.build_dir,
+ build_config.pkg_config_file())),
'doc_files': makefile_list(build_config.doc_files()),
@@ -791,13 +816,27 @@ def choose_modules_to_use(options, modules):
cannot_use_because(modname, 'loaded on request only')
elif module.load_on == 'dep':
maybe_dep.append(modname)
- elif module.load_on in ['auto', 'asm_ok']:
- if module.load_on == 'asm_ok' and not options.asm_ok:
- cannot_use_because(modname, 'uses assembly and --disable-asm set')
+
+ elif module.load_on == 'always':
+ to_load.append(modname)
+
+ elif module.load_on == 'asm_ok':
+ if options.asm_ok:
+ if options.no_autoload:
+ maybe_dep.append(modname)
+ else:
+ to_load.append(modname)
+ else:
+ cannot_use_because(modname,
+ 'uses assembly and --disable-asm set')
+ elif module.load_on == 'auto':
+ if options.no_autoload:
+ maybe_dep.append(modname)
else:
to_load.append(modname)
else:
- logging.warning('Unknown load_on %s in %s' % (module.load_on, modname))
+ logging.warning('Unknown load_on %s in %s' % (
+ module.load_on, modname))
dependency_failure = True
@@ -837,6 +876,8 @@ def choose_modules_to_use(options, modules):
logging.info('Skipping mod because %s - %s' % (
reason, ' '.join(disabled_mods)))
+ logging.debug('Loading modules %s', ' '.join(sorted(to_load)))
+
return [modules[mod] for mod in to_load]
"""
@@ -881,6 +922,11 @@ def setup_build(build_config, options, template_vars):
Copy or link the file, depending on what the platform offers
"""
def portable_symlink(filename, target_dir):
+
+ if not os.access(filename, os.R_OK):
+ logging.warning('Missing file %s' % (filename))
+ return
+
if 'symlink' in os.__dict__:
def count_dirs(dir, accum = 0):
if dir == '' or dir == os.path.curdir:
@@ -963,7 +1009,8 @@ def main(argv = None):
if argv is None:
argv = sys.argv
- logging.basicConfig(stream = sys.stdout, format = '%(message)s',
+ logging.basicConfig(stream = sys.stdout,
+ format = '%(levelname) 7s: %(message)s',
level = logging.INFO)
logging.debug('%s invoked with options "%s"' % (
@@ -1027,19 +1074,24 @@ def main(argv = None):
if options.compiler == 'gcc':
def is_64bit_arch(arch):
- if arch == 'alpha' or arch.endswith('64'):
+ 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:
- gcc_version = ''.join(
- subprocess.Popen(['g++', '-v'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).communicate())
-
- if re.search('(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])',
- gcc_version):
- options.dumb_gcc = True
+ try:
+
+ matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])'
+
+ gcc_version = ''.join(
+ subprocess.Popen(['g++', '-v'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).communicate())
+
+ if re.search(matching_version, gcc_version):
+ options.dumb_gcc = True
+ except OSError, e:
+ logging.info('Could not execute GCC for version check')
if options.dumb_gcc is True:
logging.info('Setting -fpermissive to work around gcc bug')
diff --git a/doc/api.tex b/doc/api.tex
index d52005f49..d86fa79e2 100644
--- a/doc/api.tex
+++ b/doc/api.tex
@@ -12,7 +12,7 @@
\title{\textbf{Botan API Reference}}
\author{}
-\date{2009/2/10}
+\date{2009/2/19}
\newcommand{\filename}[1]{\texttt{#1}}
\newcommand{\manpage}[2]{\texttt{#1}(#2)}
@@ -41,7 +41,7 @@
\pagebreak
\section{Introduction}
-Botan is a C++ library which attempts to provide the most common
+Botan is a C++ library that attempts to provide the most common
cryptographic algorithms and operations in an easy to use, efficient,
and portable way. It runs on a wide variety of systems, and can be
used with a number of different compilers.
@@ -156,7 +156,7 @@ should be used with the \filename{botan/} prefix in your actual code.
\subsection{Initializing the Library}
-There are a set of core services which the library needs access to
+There is a set of core services that the library needs access to
while it is performing requests. To ensure these are set up, you must
create a \type{LibraryInitializer} object (usually called 'init' in
Botan example code; 'botan\_library' or 'botan\_init' may make more
@@ -177,9 +177,9 @@ is:
at the start of your \texttt{main}.
-The constructor takes an optional string which specifies arguments.
+The constructor takes an optional string that specifies arguments.
Currently the only possible argument is ``thread\_safe'', which must
-have an boolean argument (for instance ``thread\_safe=false'' or
+have an Boolean argument (for instance ``thread\_safe=false'' or
``thread\_safe=true''). If ``thread\_safe'' is specified as true the
library will attempt to register a mutex type to properly guard access
to shared resources. However these locks do not protect individual
@@ -197,7 +197,7 @@ static member functions of \type{LibraryInitializer}, called
\type{LibraryInitializer} merely provides a convenient RAII wrapper
for the operations (thus for the internal library state as well).
-\subsection{Gotchas}
+\subsection{Pitfalls}
There are a few things to watch out for to prevent problems when using Botan.
@@ -207,7 +207,7 @@ before the library is initialized. Many Botan objects will, in their
constructor, make one or more calls into the library global state
object. Access to this object is checked, so an exception should be
thrown (rather than a memory access violation or undetected
-uninitialized object access). A rough equivalent which will work is to
+uninitialized object access). A rough equivalent that will work is to
keep a global pointer to the object, initializing it after creating
your \type{LibraryInitializer}. Merely making the
\type{LibraryInitializer} also global will probably not help, because
@@ -240,7 +240,7 @@ wondering what went wrong.
Many common uses of cryptography involve processing one or more
streams of data (be it from sockets, files, or a hardware device).
-Botan provides services which make setting up data flows through
+Botan provides services that make setting up data flows through
various operations, such as compression, encryption, and base64
encoding. Each of these operations is implemented in what are called
\emph{filters} in Botan. A set of filters are created and placed into
@@ -249,7 +249,7 @@ reaches the end, where the output is collected for retrieval. If
you're familiar with the Unix shell environment, this design will
sound quite familiar.
-Here is an example which uses a pipe to base64 encode some strings:
+Here is an example that uses a pipe to base64 encode some strings:
\begin{verbatim}
Pipe pipe(new Base64_Encoder); // pipe owns the pointer
@@ -383,13 +383,13 @@ perform more than one operation on it (\ie, encrypt it with Serpent
and calculate the SHA-256 hash of the plaintext at the same
time). That's where \type{Fork} comes in. \type{Fork} is a filter that
takes input and passes it on to \emph{one or more} \type{Filter}s
-which are attached to it. \type{Fork} changes the nature of the pipe
+that are attached to it. \type{Fork} changes the nature of the pipe
system completely. Instead of being a linked list, it becomes a tree.
Each \type{Filter} in the fork is given its own output buffer, and
thus its own message. For example, if you had previously written two
messages into a \type{Pipe}, then you start a new one with a
-\type{Fork} which has three paths of \type{Filter}'s inside it, you
+\type{Fork} that has three paths of \type{Filter}'s inside it, you
add three new messages to the \type{Pipe}. The data you put into the
\type{Pipe} is duplicated and sent into each set of \type{Filter}s,
and the eventual output is placed into a dedicated message slot in the
@@ -421,7 +421,7 @@ NULL pointers), message 2 will be the output of the second
allocated in a top to bottom fashion, when looked at on the screen. However,
note that there could be potential for bugs if this is not anticipated. For
example, if your code is passed a \type{Filter}, and you assume it is a
-``normal'' one which only uses one message, your message offsets would be
+``normal'' one that only uses one message, your message offsets would be
wrong, leading to some confusion during output.
If Fork's first argument is a null pointer, but a later argument is
@@ -451,7 +451,7 @@ Here we wanted to not only decrypt the message, but send the decrypted
text through an additional computation, in order to compute the
authentication code.
-Any \type{Filter}s which are attached to the \type{Pipe} after the
+Any \type{Filter}s that are attached to the \type{Pipe} after the
\type{Fork} are implicitly attached onto the first branch created by
the fork. For example, let's say you created this \type{Pipe}:
@@ -476,7 +476,7 @@ out of a function, or to a \type{Fork} constructor.
You can call \type{Chain}'s constructor with up to 4 \type{Filter*}s
(they will be added in order), or with an array of \type{Filter*}s and
-a \type{u32bit} which tells \type{Chain} how many \type{Filter*}s are
+a \type{u32bit} that tells \type{Chain} how many \type{Filter*}s are
in the array (again, they will be attached in order). Here's the
example from the last section, using chain instead of relying on the
obscure rule that version used.
@@ -497,7 +497,7 @@ By default, \type{Pipe} will do nothing at all; any input placed into
the \type{Pipe} will be read back unchanged. Obviously, this has
limited utility, and presumably you want to use one or more
\type{Filter}s to somehow process the data. First, you can choose a
-set of \type{Filter}s to initialize the \type{Pipe} with via the
+set of \type{Filter}s to initialize the \type{Pipe} via the
constructor. You can pass it either a set of up to 4 \type{Filter*}s,
or a pre-defined array and a length:
@@ -523,8 +523,8 @@ use; that is, either before calling \function{start\_msg}, or after
have been made yet).
The function \function{reset}() simply removes all the \type{Filter}s
-which the \type{Pipe} is currently using~--~it is reset to an
-initialize, ``empty'' state. Any data which is being retained by the
+that the \type{Pipe} is currently using~--~it is reset to an
+initialize, ``empty'' state. Any data that is being retained by the
\type{Pipe} is retained after a \function{reset}(), and
\function{reset}() does not affect the message numbers (discussed
later).
@@ -533,7 +533,7 @@ Calling \function{prepend} and \function{append} will either prepend
or append the passed \type{Filter} object to the list of
transformations. For example, if you \function{prepend} a
\type{Filter} implementing encryption, and the \type{Pipe} already had
-a \type{Filter} which hex encoded the input, then the next set of
+a \type{Filter} that hex encoded the input, then the next set of
input would be first encrypted, then hex encoded. Alternately, if you
called \function{append}, then the input would be first be hex
encoded, and then encrypted (which is not terribly useful in this
@@ -557,7 +557,7 @@ contains. Writes at any other time are invalid, and will result in an
exception.
As to writing, you can call any of the functions called \function{write}(),
-which can take any of: a \type{byte[]}/\type{u32bit} pair, a
+that can take any of: a \type{byte[]}/\type{u32bit} pair, a
\type{SecureVector<byte>}, a \type{std::string}, a \type{DataSource\&}, or a
single \type{byte}.
@@ -566,7 +566,7 @@ you can use the \function{process\_msg} series of functions, which start a
message, write their argument into the \type{Pipe}, and then end the
message. In this case you would not make any explicit calls to
\function{start\_msg}/\function{end\_msg}. The version of \function{write}
-which takes a single \type{byte} is not supported by \function{process\_msg},
+that takes a single \type{byte} is not supported by \function{process\_msg},
but all the other variants are.
\type{Pipe} can also be used with the \verb|>>| operator, and will accept a
@@ -579,7 +579,7 @@ read into the \type{Pipe}.
Retrieving the processed data from a \type{Pipe} is a bit more complicated, for
various reasons. In particular, because \type{Pipe} will separate each message
into a separate buffer, you have to be able to retrieve data from each message
-independently. Each of \type{Pipe}'s read functions has a final parameter which
+independently. Each of \type{Pipe}'s read functions has a final parameter that
specifies what message to read from (as a 32-bit integer). If this parameter is
set to \type{Pipe::DEFAULT\_MESSAGE}, it will read the current default message
(\type{DEFAULT\_MESSAGE} is also the default value of this parameter). The
@@ -598,7 +598,7 @@ destructive operation with a \type{Pipe}).
There are also the functions \type{SecureVector<byte>} \function{read\_all}(),
and \type{std::string} \function{read\_all\_as\_string}(), which return the
entire contents of the message, either as a memory buffer, or a
-\type{std::string} (which is generally only useful is the \type{Pipe} has
+\type{std::string} (which is generally only useful if the \type{Pipe} has
encoded the message into a text string, such as when a \type{Base64\_Encoder}
is used).
@@ -617,7 +617,7 @@ using the output operator.
\subsection{A Filter Example}
-Here is some code which takes one or more filenames in \arg{argv} and
+Here is some code that takes one or more filenames in \arg{argv} and
calculates the result of several hash functions for each file. The complete
program can be found as \filename{hasher.cpp} in the Botan distribution. For
brevity, most error checking has been removed.
@@ -708,8 +708,8 @@ Here's a example:
pipe.end_msg();
\end{verbatim}
-There are some requirements to using \type{Keyed\_Filter} which you must
-follow. If you call \function{set\_key} or \function{set\_iv} on a filter which
+There are some requirements to using \type{Keyed\_Filter} that you must
+follow. If you call \function{set\_key} or \function{set\_iv} on a filter that
is owned by a \type{Pipe}, you must do so while the \type{Pipe} is
``unlocked''. This refers to the times when no messages are being processed by
\type{Pipe} -- either before \type{Pipe}'s \function{start\_msg} is called, or
@@ -819,7 +819,7 @@ exceptionally long, strange, and probably useless name
There are four classes in this category, \type{PK\_Encryptor\_Filter},
\type{PK\_Decryptor\_Filter}, \type{PK\_Signer\_Filter}, and
\type{PK\_Verifier\_Filter}. Each takes a pointer to an object of the
-appropriate type (\type{PK\_Encryptor}, \type{PK\_Decryptor}, etc) which is
+appropriate type (\type{PK\_Encryptor}, \type{PK\_Decryptor}, etc) that is
deleted by the destructor. These classes are found in \filename{pk\_filts.h}.
Three of these, for encryption, decryption, and signing are pretty much
@@ -845,7 +845,7 @@ Cryptography'' in this manual.
\subsubsection{Encoders}
Often you want your data to be in some form of text (for sending over channels
-which aren't 8-bit clean, printing it, etc). The filters \type{Hex\_Encoder}
+that aren't 8-bit clean, printing it, etc). The filters \type{Hex\_Encoder}
and \type{Base64\_Encoder} will convert arbitrary binary data into hex or
base64 formats. Not surprisingly, you can use \type{Hex\_Decoder} and
\type{Base64\_Decoder} to convert it back into its original form.
@@ -929,8 +929,8 @@ Additionally, if necessary, filters can define a constructor that takes any
needed arguments, and a destructor to deal with deallocating memory, closing
files, etc.
-There is also a \type{BufferingFilter} class (in \filename{buf\_filt.h}) which
-will take a message and split it up into an initial block which can be of any
+There is also a \type{BufferingFilter} class (in \filename{buf\_filt.h}) that
+will take a message and split it up into an initial block that can be of any
size (including zero), a sequence of fixed sized blocks of any non-zero size,
and last (possibly zero-sized) final block. This might make a useful base class
for your filters, depending on what you have in mind.
@@ -1018,12 +1018,12 @@ Most public key algorithms have limitations or restrictions on their
parameters. For example RSA requires an odd exponent, and algorithms based on
the discrete logarithm problem need a generator $> 1$.
-Each low-level public key type has a function named \function{check\_key} which
-takes a \type{bool}. This function returns a boolean value that declares
+Each low-level public key type has a function named \function{check\_key} that
+takes a \type{bool}. This function returns a Boolean value that declares
whether or not the key is valid (from an algorithmic standpoint). For example,
it will check to make sure that the prime parameters of a DSA key are, in fact,
prime. It does not have anything to do with the validity of the key for any
-particular use, nor does it have anything to do with certificates which link a
+particular use, nor does it have anything to do with certificates that link a
key (which, after all, is just some numbers) with a user or other entity. If
\function{check\_key}'s argument is \type{true}, then it does ``strong''
checking, which includes fairly expensive operations like primality checking.
@@ -1094,7 +1094,7 @@ If you attempt an operation with a larger size than the key can
support (this limit varies based on the algorithm, the key size, and
the padding method used (if any)), an exception will be
thrown. Alternately, you can call \function{maximum\_input\_size},
-which will return the maximum size you can safely encrypt. In fact,
+that will return the maximum size you can safely encrypt. In fact,
you can often encrypt an object that is one byte longer, but only if
enough of the high bits of the leading byte are set to zero. Since
this is pretty dicey, it's best to stick with the advertised maximum.
@@ -1143,7 +1143,7 @@ a message digest function to hash the message with. Raw actually signs the
input directly; if the message is too big, the signing operation will fail. Raw
is not useful except in very specialized applications.
-There are various interactions which make certain encoding schemes and signing
+There are various interactions that make certain encoding schemes and signing
algorithms more or less useful.
EMSA2 is the usual method for encoding Rabin-William signatures, so for
@@ -1171,7 +1171,7 @@ meaning the output of the primitive itself is returned as the key, or
``KDF1(hash)'' or ``KDF2(hash)'' where ``hash'' is any string you happen to
like (hopefully you like strings like ``SHA-256'' or ``RIPEMD-160''), or
``X9.42-PRF(keywrap)'', which uses the PRF specified in ANSI X9.42. It takes
-the name or OID of the key wrap algorithm which will be used to encrypt a
+the name or OID of the key wrap algorithm that will be used to encrypt a
content encryption key.
How key agreement generally works is that you trade public values with some
@@ -1185,12 +1185,12 @@ key you want.
Depending on the key derivation function you're using, you many not
\emph{actually} get back a key of that size. In particular, ``Raw'' will return
a number about the size of the Diffie-Hellman modulus, and KDF1 can only return
-a key which is the same size as the output of the hash. KDF2, on the other
+a key that is the same size as the output of the hash. KDF2, on the other
hand, will always give you a key exactly as long as you request, regardless of
the underlying hash used with it. The key returned is a \type{SymmetricKey},
ready to pass to a block cipher, MAC, or other symmetric algorithm.
-The public value which should be used can be obtained by calling
+The public value that should be used can be obtained by calling
\function{public\_data}, which exists for any key that is associated with a
key agreement algorithm. It returns a \type{SecureVector<byte>}.
@@ -1221,7 +1221,7 @@ manual.
\subsubsection{Public Keys}
-The interfaces for doing either of these is quite similar. Let's look at the
+The interfaces for doing either of these are quite similar. Let's look at the
X.509 stuff first:
\begin{verbatim}
namespace X509 {
@@ -1257,7 +1257,7 @@ course, the source is in fact storing a representation of a public
key). The encoding used (PEM or BER) need not be specified; the format
will be detected automatically. The key is allocated with
\function{new}, and should be released with \function{delete} when you
-are done with it. The first takes a generic \type{DataSource} which
+are done with it. The first takes a generic \type{DataSource} that
you have to allocate~--~the others are simple wrapper functions that
take either a filename or a memory buffer.
@@ -1351,11 +1351,11 @@ There may be some strange programs out there that support the v2.0 extensions
to PBES1 but not PBES2; if you need to inter-operate with a program like that,
use ``PBE-PKCS5v15(MD5,RC2/CBC)''. For example, OpenSSL supports this format
(though since it also supports the v2.0 schemes, there is no reason not to just
-use TripleDES or AES). This scheme uses a 64 bit key, which, while
-significantly better than a 56 bit key, is a bit too small for comfort.
+use TripleDES or AES). This scheme uses a 64-bit key that, while
+significantly better than a 56-bit key, is a bit too small for comfort.
-Last but not least, there are some functions which is basically identical to
-\function{X509::load\_key}, which will load, and possibly decrypt, a PKCS \#8
+Last but not least, there are some functions that are basically identical to
+\function{X509::load\_key} that will load, and possibly decrypt, a PKCS \#8
private key:
\begin{verbatim}
@@ -1393,7 +1393,7 @@ it once you are done with it.
As of now Nyberg-Rueppel and Rabin-Williams keys cannot be imported or
exported, because they have no official ASN.1 OID or definition. ElGamal keys
can (as of Botan 1.3.8) be imported and exported, but the only other
-implementation which supports the format is Peter Gutmann's Cryptlib. If you
+implementation that supports the format is Peter Gutmann's Cryptlib. If you
can help it, stick to RSA and DSA.
\emph{Note}: Currently NR and RW are given basic ASN.1 key formats (which
@@ -1401,7 +1401,7 @@ mirror DSA and RSA, respectively), which means that, if they are assigned an
OID, they can be imported and exported just as easily as RSA and DSA. You can
assign them an OID by putting a line in a Botan configuration file, calling
\function{OIDS::add\_oid}, or editing \filename{src/policy.cpp}. Be warned that
-it is possible that a future version will use a format which is different from
+it is possible that a future version will use a format that is different from
the current one (\ie, a newly standardized format).
\pagebreak
@@ -1410,8 +1410,8 @@ the current one (\ie, a newly standardized format).
A certificate is essentially a binding between some identifying information of
a person or other entity (called a \emph{subject}) and a public key. This
binding is asserted by a signature on the certificate, which is placed there by
-some authority (the \emph{issuer}) which at least claims that it knows the
-subject that is named in the certificate really ``owns'' the private key
+some authority (the \emph{issuer}) that at least claims that it knows the
+subject named in the certificate really ``owns'' the private key
corresponding to the public key in the certificate.
The major certificate format in use today is X.509v3, designed by ISO and
@@ -1468,13 +1468,13 @@ to accept or return a \type{std::wstring} instead of a \type{std::string}).
Like the distinguished names, subject alternative names can contain a lot of
things that Botan will flat out ignore (most of which you would never actually
-want to use). However, there are three very useful pieces of information which
+want to use). However, there are three very useful pieces of information that
this extension might hold: an email address (``[email protected]''), a DNS name
(``somehost.site2.com''), or a URI (``http://www.site3.com'').
So, how to get the information? Simply call \function{subject\_info} with the
name of the piece of information you want, and it will return a
-\type{std::string} which is either empty (signifying that the certificate
+\type{std::string} that is either empty (signifying that the certificate
doesn't have this information), or has the information requested. There are
several names for each possible item, but the most easily readable ones are:
``Name'', ``Country'', ``Organization'', ``Organizational Unit'', ``Locality'',
@@ -1526,7 +1526,7 @@ compromised, or the user to which it has been assigned leaving an
organization. Certificate revocation lists are an answer to this problem
(though online certificate validation techniques are starting to become
somewhat more popular). Essentially, every once in a while the CA will release
-a CRL, listing all certificates which have been revoked. Also included is
+a CRL, listing all certificates that have been revoked. Also included is
various pieces of information like what time a particular certificate was
revoked, and for what reason. In most systems, it is wise to support some form
of certificate revocation, and CRLs handle this fairly easily.
@@ -1588,8 +1588,8 @@ The versions that take a \type{DataSource\&} will add all the certificates
that it can find in that source.
All of them add the cert(s) to the store. The 'trusted' certificates are the
-ones which you have some reason to trust are genuine. For example, say your
-application is working with certificates which are owned by employees of some
+ones that you have some reason to trust are genuine. For example, say your
+application is working with certificates that are owned by employees of some
company, and all of their certificates are signed by the company CA, whose
certificate is in turned signed by a commercial root CA. What you would then do
is include the certificate of the commercial CA with your application, and read
@@ -1663,11 +1663,11 @@ subjectAlternativeName extension). The name and email versions take a
\type{std::string}, while the SKID version takes a \type{SecureVector<byte>}
containing the subject key identifier in raw binary. You can choose not to
implement \function{by\_name} or \function{by\_email}, but \function{by\_SKID}
-is mandatory to implement, and, currently, is the only version which is used by
+is mandatory to implement, and, currently, is the only version that is used by
\type{X509\_Store}.
Finally, there is a method for finding CRLs, called \function{get\_crls\_for},
-which takes an \type{X509\_Certificate} object, and returns a
+that takes an \type{X509\_Certificate} object, and returns a
\type{std::vector} of \type{X509\_CRL}. While generally there will be only one
CRL, the use of the vector makes it easy to return no CRLs (\eg, if the
certificate store doesn't support retrieving them), or return multiple ones
@@ -1779,7 +1779,7 @@ a CA object is done by the following constructor:
X509_CA(const X509_Certificate& cert, const PKCS8_PrivateKey& key);
\end{verbatim}
-The private key is the private key corresponding to the public key in the the
+The private key is the private key corresponding to the public key in the
CA's certificate.
Generally, requests for new certificates are supplied to a CA in the form on
@@ -1812,8 +1812,8 @@ be used. If not, then \arg{seconds} specifies how long (in seconds) it will be
until the CRL's next update time (after this time, most clients will reject the
CRL as too old).
-On the other hand, you may have issued a CRL before. In which case, you will
-want to issue a new CRL which contains both all previously revoked
+On the other hand, you may have issued a CRL before. In that case, you will
+want to issue a new CRL that contains all previously revoked
certificates, along with any new ones. This is done by calling the
\type{X509\_CA} member function
\function{update\_crl}(\type{X509\_CRL}~\arg{old\_crl},
@@ -1823,13 +1823,13 @@ CA issued, and \arg{new\_revoked} is a list of any newly revoked certificates.
The function returns a new \type{X509\_CRL} to make available for clients. The
semantics for the \arg{seconds} argument is the same as \function{new\_crl}.
-The \type{CRL\_Entry} type is a structure which contains, at a minimum, the
+The \type{CRL\_Entry} type is a structure that contains, at a minimum, the
serial number of the revoked certificate. As serial numbers are never repeated,
the pairing of an issuer and a serial number (should) distinctly identify any
certificate. In this case, we represent the serial number as a
\type{SecureVector<byte>} called \arg{serial}. There are two additional
-(optional) values, an enumeration called \type{CRL\_Code} which specifies the
-reason for revocation (\arg{reason}), and an object which represents the time
+(optional) values, an enumeration called \type{CRL\_Code} that specifies the
+reason for revocation (\arg{reason}), and an object that represents the time
that the certificate became invalid (if this information is known).
If you wish to remove an old entry from the CRL, insert a new entry for the
@@ -1853,7 +1853,7 @@ namespace X509 {
Where \arg{key} is obviously the private key you wish to use (the public key,
used in the certificate itself, is extracted from the private key), and
-\arg{opts} is an structure which has various bits of information which will be
+\arg{opts} is an structure that has various bits of information that will be
used in creating the certificate (this structure, and its use, is discussed
below). This function is found in the header \filename{x509self.h}. There is an
example of using this function in the \filename{self\_sig} example.
@@ -1879,7 +1879,7 @@ minted X.509 certificate. There is an example of using this function in the
\subsubsection{Certificate Options}
So what is this \type{X509\_Cert\_Options} thing we've been passing around?
-Basically, it's a bunch of information which will end up being stored into the
+Basically, it's a bunch of information that will end up being stored into the
certificate. This information comes in 3 major flavors: information about the
subject (CA or end-user), the validity period of the certificate, and
restrictions on the usage of the certificate.
@@ -1891,7 +1891,7 @@ various bits of information about the user: \arg{common\_name},
many of these as possible should be filled it (especially an email address),
though the only required ones are \arg{common\_name} and \arg{country}.
-There is another value which is only useful when creating a PKCS \#10 request,
+There is another value that is only useful when creating a PKCS \#10 request,
which is called \arg{challenge}. This is a challenge password, which you can
later use to request certificate revocation (\emph{if} the CA supports doing
revocations in this manner).
@@ -1903,7 +1903,7 @@ valid, and when it should stop being valid. If you don't set the starting
validity period, it will automatically choose the current time. If you don't
set the ending time, it will choose the starting time plus a default time
period. The arguments to these functions specify the time in the following
-format: ``2002/11/27 1:50:14''. The time is in 24 hour format, and the date is
+format: ``2002/11/27 1:50:14''. The time is in 24-hour format, and the date is
encoded as year/month/day. The date must be specified, but you can omit the
time or trailing parts of it, for example ``2002/11/27 1:50'' or
``2002/11/27''.
@@ -1926,9 +1926,9 @@ simply not call \function{add\_constraints}, in which case the appropriate
values will be chosen for you.
The second function, \function{add\_ex\_constraints}, allows you to specify an
-OID which has some meaning with regards to restricting the key to particular
-usages. You can, if you wish, specify any OID you like, but there are a set of
-standard ones which other applications will be able to understand. These are
+OID that has some meaning with regards to restricting the key to particular
+usages. You can, if you wish, specify any OID you like, but there is a set of
+standard ones that other applications will be able to understand. These are
the ones specified by the PKIX standard, and are named ``PKIX.ServerAuth'' (for
TLS server authentication), ``PKIX.ClientAuth'' (for TLS client
authentication), ``PKIX.CodeSigning'', ``PKIX.EmailProtection'' (most likely
@@ -2102,7 +2102,7 @@ Stream ciphers implement the \type{SymmetricAlgorithm} interface.
Some stream ciphers support random access to any point in their cipher
stream. For such ciphers, calling \type{void} \function{seek}(\type{u32bit}
-\arg{byte}) will change the cipher's state so that it as if the cipher had been
+\arg{byte}) will change the cipher's state so that it is as if the cipher had been
keyed as normal, then encrypted \arg{byte} -- 1 bytes of data (so the next byte
in the cipher stream is byte number \arg{byte}).
@@ -2140,14 +2140,14 @@ The second method of using final is to call it with no arguments at all, as
shown in the second prototype. It will return the hash/mac value in a memory
buffer, which will have size OUTPUT\_LENGTH.
-There are also a pair of functions called \function{process}. They are
+There is also a pair of functions called \function{process}. They are
essentially a combination of a single \function{update}, and \function{final}.
Both versions return the final value, rather than placing it an array. Calling
\function{process} with a single byte value isn't available, mostly because it
would rarely be useful.
A MAC can be viewed (in most cases) as simply a keyed hash function, so classes
-which are derived from \type{MessageAuthenticationCode} have \function{update}
+that are derived from \type{MessageAuthenticationCode} have \function{update}
and \function{final} classes just like a \type{HashFunction} (and like a
\type{HashFunction}, after \function{final} is called, it can be used to make a
new MAC right away; the key is kept around).
@@ -2159,7 +2159,7 @@ A MAC has the \type{SymmetricAlgorithm} interface in addition to the
\section{Random Number Generators}
The random number generators provided in Botan are meant for creating keys,
-IVs, padding, nonces, and anything else which requires 'random' data. It is
+IVs, padding, nonces, and anything else that requires 'random' data. It is
important to remember that the output of these classes will vary, even if they
are supplied with exactly the same seed (\ie, two \type{Randpool} objects with
similar initial states will not produce the same output, because the value of
@@ -2257,14 +2257,14 @@ namespace.
Note for writers of \type{EntropySource}s: it isn't necessary to use any kind
of cryptographic hash on your output. The data produced by an EntropySource is
only used by an application after it has been hashed by the
-\type{RandomNumberGenerator} which asked for the entropy, thus any hashing
+\type{RandomNumberGenerator} that asked for the entropy, thus any hashing
you do will be wasteful of both CPU cycles and possibly entropy.
\pagebreak
\section{User Interfaces}
Botan has recently changed some infrastructure to better accommodate more
-complex user interfaces, in particular ones which are based on event
+complex user interfaces, in particular ones that are based on event
loops. Primary among these was the fact that when doing something like loading
a PKCS \#8 encoded private key, a passphrase might be needed, but then again it
might not (a PKCS \#8 key doesn't have to be encrypted). Asking for a
@@ -2313,7 +2313,7 @@ exception will be thrown; your UI should assume this can happen, and provide
appropriate error handling (such as putting up a dialog box informing the user
of the situation, and canceling the operation in progress).
-There is an example \type{UI} which uses GTK+ available on the web site. The
+There is an example \type{UI} that uses GTK+ available on the web site. The
\type{GTK\_UI} code is cleanly separated from the rest of the example, so if
you happen to be using GTK+, you can copy (and/or adapt) that code for your
application. If you write a \type{UI} object for another windowing system
@@ -2324,7 +2324,7 @@ MIT/BSD), feel free to send in a copy.
\pagebreak
\section{Botan's Modules}
-Botan comes with a variety of modules which can be compiled into the system.
+Botan comes with a variety of modules that can be compiled into the system.
These will not be available on all installations of the library, but you can
check for their availability based on whether or not certain macros are
defined.
@@ -2375,7 +2375,7 @@ of this type around and run fast polls ever few minutes.
\noindent
\type{FTW\_EntropySource}: Walk through a filesystem (the root to start
searching is passed as a string to the constructor), reading files. This tends
-to only be useful on things like \filename{/proc} which have a great deal of
+to only be useful on things like \filename{/proc} that have a great deal of
variability over time, and even then there is only a small amount of entropy
gathered: about 1 bit of entropy for every 16 bits of output (and many hundreds
of bits are read in order to get that 16 bits). It is declared in
@@ -2384,11 +2384,11 @@ use this as a last resort. I don't really trust it, and neither should you.
\noindent
\type{Win32\_CAPI\_EntropySource}: This routines gathers entropy from a Win32
-CAPI module. It takes an optional \type{std::string} which will specify what
+CAPI module. It takes an optional \type{std::string} that will specify what
type of CAPI provider to use. Generally the CAPI RNG is always the same
-software-based PRNG, but there are a few which may use a hardware RNG. By
+software-based PRNG, but there are a few that may use a hardware RNG. By
default it will use the first provider listed in the option
-``rng/ms\_capi\_prov\_type'' which is available on the machine (currently the
+``rng/ms\_capi\_prov\_type'' that is available on the machine (currently the
providers ``RSA\_FULL'', ``INTEL\_SEC'', ``FORTEZZA'', and ``RNG'' are
recognized).
@@ -2400,7 +2400,7 @@ APIs.
\type{Pthread\_EntropySource}: Attempt to gather entropy based on jitter
between a number of threads competing for a single mutex. This entropy source
is \emph{very} slow, and highly questionable in terms of security. However, it
-provides a worst-case fallback on systems which don't have Unix-like features,
+provides a worst-case fallback on systems that don't have Unix-like features,
but do support POSIX threads. This module is currently unavailable due to
problems on some systems.
@@ -2495,12 +2495,12 @@ up a file with that name and read from it.
\subsubsection{Data Sinks}
-A \type{DataSink} (in \filename{data\_snk.h}) is a \type{Filter} which takes
+A \type{DataSink} (in \filename{data\_snk.h}) is a \type{Filter} that takes
arbitrary amounts of input, and produces no output. Generally, this means it's
doing something with the data outside the realm of what
\type{Filter}/\type{Pipe} can handle, for example, writing it to a file (which
is what the \type{DataSink\_Stream} does). There is no need for
-\type{DataSink}s which write to a \type{std::string} or memory buffer, because
+\type{DataSink}s that write to a \type{std::string} or memory buffer, because
\type{Pipe} can handle that by itself.
Here's a quick example of using a \type{DataSink}, which encrypts
@@ -2643,7 +2643,7 @@ recommend for new applications.
\subsubsection{OpenPGP S2K}
-There are some oddities about OpenPGP's S2K algorithms which are documented
+There are some oddities about OpenPGP's S2K algorithms that are documented
here. For one thing, it uses the iteration count in a strange manner; instead
of specifying how many times to iterate the hash, it tells how many
\emph{bytes} should be hashed in total (including the salt). So the exact
@@ -2697,7 +2697,7 @@ standard ones.
\subsection{Threads and Mutexes}
Botan includes a mutex system, which is used internally to lock some shared
-data structures which must be kept shared for efficiency reasons (mostly, these
+data structures that must be kept shared for efficiency reasons (mostly, these
are in the allocation systems~--~handing out 1000 separate allocators hurts
performance and makes caching memory blocks useless). This system is supported
by the \texttt{mux\_pthr} module, implementing the \type{Mutex} interface for
@@ -2715,7 +2715,7 @@ A major concern with mixing modern multiuser OSes and cryptographic
code is that at any time the code (including secret keys) could be
swapped to disk, where it can later be read by an attacker. Botan
stores almost everything (and especially anything sensitive) in memory
-buffers which a) clear out their contents when their destructors are
+buffers that a) clear out their contents when their destructors are
called, and b) have easy plugins for various memory locking functions,
such as the \function{mlock}(2) call on many Unix systems.
@@ -2816,7 +2816,7 @@ and
\type{BigInt} \function{BigInt::decode}(\type{SecureVector<byte>},
\type{Encoding})
-\type{Encoding} is an enum which has values \type{Binary}, \type{Octal},
+\type{Encoding} is an enum that has values \type{Binary}, \type{Octal},
\type{Decimal}, and \type{Hexadecimal}. The parameter will default to
\type{Binary}. These functions are static member functions, so they would be
called like this:
@@ -2945,7 +2945,7 @@ PKCS \#10}
\noindent
There is also support for the very general standards of \textbf{IEEE 1363-2000}
and \textbf{1363a}. Most of the contents of such are included in the standards
-mentioned above, in various forms (usually with extra restrictions which 1363
+mentioned above, in various forms (usually with extra restrictions that 1363
does not impose).
\subsection{Algorithms Listing}
@@ -2955,7 +2955,7 @@ nearly all cases, you never need to know the header file or type name
to use them. However, you do need to know what string (or strings) are
used to identify that algorithm. Generally, these names conform to
those set out by SCAN (Standard Cryptographic Algorithm Naming), which
-is a document which specifies how strings are mapped onto algorithm
+is a document that specifies how strings are mapped onto algorithm
objects, which is useful for a wide variety of crypto APIs (SCAN is
oriented towards Java, but Botan and several other non-Java libraries
also make at least some use of it). For full details, read the SCAN
@@ -3008,7 +3008,7 @@ match that in SCAN, if it's defined there).
Generally, cryptographic algorithms are well standardized, thus
compatibility between implementations is relatively simple (of course, not all
algorithms are supported by all implementations). But there are a few
-algorithms which are poorly specified, and these should be avoided if you wish
+algorithms that are poorly specified, and these should be avoided if you wish
your data to be processed in the same way by another implementation (including
future versions of Botan).
@@ -3027,7 +3027,7 @@ algorithms, TripleDES, AES, HMAC, and SHA-256 all being good examples.
Some of the algorithms implemented by Botan may be covered by patents in some
locations. Algorithms known to have patent claims on them in the United States
-and which are not available in a license-free/royalty-free manner include:
+and that are not available in a license-free/royalty-free manner include:
IDEA, MISTY1, RC5, RC6, and Nyberg-Rueppel.
You must not assume that, just because an algorithm is not listed here, it is
diff --git a/doc/credits.txt b/doc/credits.txt
index fbc1fb796..ef2ee6bc1 100644
--- a/doc/credits.txt
+++ b/doc/credits.txt
@@ -11,6 +11,11 @@
S - meatspace location
----------
+N - Charles Brockman
+W - http://www.securitygenetics.com/
+D - documentation editing
+S - Oregon, USA
+
N: Martin Doering
D: GF(p) arithmetic
diff --git a/doc/examples/bench.cpp b/doc/examples/bench.cpp
new file mode 100644
index 000000000..37ef1104d
--- /dev/null
+++ b/doc/examples/bench.cpp
@@ -0,0 +1,98 @@
+#include <botan/benchmark.h>
+#include <botan/init.h>
+#include <botan/auto_rng.h>
+#include <botan/libstate.h>
+
+using namespace Botan;
+
+#include <iostream>
+
+double best_speed(const std::string& algorithm,
+ u32bit milliseconds,
+ RandomNumberGenerator& rng,
+ Timer& timer)
+ {
+ std::map<std::string, double> speeds =
+ algorithm_benchmark(algorithm, milliseconds,
+ timer, rng,
+ global_state().algorithm_factory());
+
+ double best_time = 0;
+
+ for(std::map<std::string, double>::const_iterator i = speeds.begin();
+ i != speeds.end(); ++i)
+ if(i->second > best_time)
+ best_time = i->second;
+
+ return best_time;
+ }
+
+const std::string algos[] = {
+ "AES-128",
+ "AES-192",
+ "AES-256",
+ "Blowfish",
+ "CAST-128",
+ "CAST-256",
+ "DES",
+ "DESX",
+ "TripleDES",
+ "GOST",
+ "IDEA",
+ "KASUMI",
+ "Lion(SHA-256,Turing,8192)",
+ "Luby-Rackoff(SHA-512)",
+ "MARS",
+ "MISTY1",
+ "Noekeon",
+ "RC2",
+ "RC5(12)",
+ "RC5(16)",
+ "RC6",
+ "SAFER-SK(10)",
+ "SEED",
+ "Serpent",
+ "Skipjack",
+ "Square",
+ "TEA",
+ "Twofish",
+ "XTEA",
+ "Adler32",
+ "CRC32",
+ "FORK-256",
+ "GOST-34.11",
+ "HAS-160",
+ "HAS-V",
+ "MD2",
+ "MD4",
+ "MD5",
+ "RIPEMD-128",
+ "RIPEMD-160",
+ "SHA-160",
+ "SHA-256",
+ "SHA-384",
+ "SHA-512",
+ "Skein-512",
+ "Tiger",
+ "Whirlpool",
+ "CMAC(AES-128)",
+ "HMAC(SHA-1)",
+ "X9.19-MAC",
+ "",
+};
+
+int main()
+ {
+ LibraryInitializer init;
+
+ u32bit milliseconds = 1000;
+ AutoSeeded_RNG rng;
+ Default_Benchmark_Timer timer;
+
+ for(u32bit i = 0; algos[i] != ""; ++i)
+ {
+ std::string algo = algos[i];
+ std::cout << algo << ' '
+ << best_speed(algo, milliseconds, rng, timer) << "\n";
+ }
+ }
diff --git a/doc/examples/cryptobox.cpp b/doc/examples/cryptobox.cpp
new file mode 100644
index 000000000..0a769b0cd
--- /dev/null
+++ b/doc/examples/cryptobox.cpp
@@ -0,0 +1,50 @@
+/*
+* Cryptobox example
+*/
+#include <botan/botan.h>
+#include <botan/cryptobox.h>
+#include <fstream>
+#include <iostream>
+#include <vector>
+
+using namespace Botan;
+
+int main(int argc, char* argv[])
+ {
+ LibraryInitializer init;
+
+ AutoSeeded_RNG rng;
+
+ if(argc != 3)
+ {
+ std::cout << "Usage: cryptobox pass filename\n";
+ return 1;
+ }
+
+ std::string pass = argv[1];
+ std::string filename = argv[2];
+
+ std::ifstream input(filename.c_str());
+
+ std::vector<byte> file_contents;
+ while(input.good())
+ {
+ byte filebuf[4096] = { 0 };
+ input.read((char*)filebuf, sizeof(filebuf));
+ size_t got = input.gcount();
+
+ file_contents.insert(file_contents.end(), filebuf, filebuf+got);
+ }
+
+ std::string ciphertext = CryptoBox::encrypt(&file_contents[0],
+ file_contents.size(),
+ pass, rng);
+
+ std::cout << ciphertext;
+
+ /*
+ std::cout << CryptoBox::decrypt((const byte*)&ciphertext[0],
+ ciphertext.length(),
+ pass);
+ */
+ }
diff --git a/doc/examples/gen_certs.cpp b/doc/examples/gen_certs.cpp
new file mode 100644
index 000000000..f635e1ccf
--- /dev/null
+++ b/doc/examples/gen_certs.cpp
@@ -0,0 +1,124 @@
+/*
+* Generate a root CA plus httpd, dovecot, and postfix certs/keys
+*
+*/
+
+#include <botan/botan.h>
+#include <botan/rsa.h>
+#include <botan/util.h>
+#include <botan/x509self.h>
+#include <botan/x509_ca.h>
+
+using namespace Botan;
+
+#include <iostream>
+#include <fstream>
+
+void fill_commoninfo(X509_Cert_Options& opts)
+ {
+ opts.country = "US";
+ opts.organization = "randombit.net";
+ opts.email = "[email protected]";
+ opts.locality = "Vermont";
+ }
+
+X509_Certificate make_ca_cert(RandomNumberGenerator& rng,
+ const Private_Key& priv_key,
+ const X509_Time& now,
+ const X509_Time& later)
+ {
+ X509_Cert_Options opts;
+ fill_commoninfo(opts);
+ opts.common_name = "randombit.net CA";
+ opts.start = now;
+ opts.end = later;
+ opts.CA_key();
+
+ return X509::create_self_signed_cert(opts, priv_key, rng);
+ }
+
+PKCS10_Request make_server_cert_req(const Private_Key& key,
+ const std::string& hostname,
+ RandomNumberGenerator& rng)
+ {
+ X509_Cert_Options opts;
+ opts.common_name = hostname;
+ fill_commoninfo(opts);
+
+ opts.add_ex_constraint("PKIX.ServerAuth");
+
+ return X509::create_cert_req(opts, key, rng);
+ }
+
+void save_pair(const std::string& name,
+ const std::string& password,
+ const X509_Certificate& cert,
+ const Private_Key& key,
+ RandomNumberGenerator& rng)
+ {
+ std::string cert_fsname = name + "_cert.pem";
+ std::string key_fsname = name + "_key.pem";
+
+ std::ofstream cert_out(cert_fsname.c_str());
+ cert_out << cert.PEM_encode() << "\n";
+ cert_out.close();
+
+ std::ofstream key_out(key_fsname.c_str());
+ if(password != "")
+ key_out << PKCS8::PEM_encode(key, rng, password);
+ else
+ key_out << PKCS8::PEM_encode(key);
+ key_out.close();
+ }
+
+int main()
+ {
+ const u32bit seconds_in_a_year = 31556926;
+
+ const u32bit current_time = system_time();
+
+ X509_Time now = X509_Time(current_time);
+ X509_Time later = X509_Time(current_time + 4*seconds_in_a_year);
+
+ LibraryInitializer init;
+
+ AutoSeeded_RNG rng;
+
+ RSA_PrivateKey ca_key(rng, 2048);
+
+ X509_Certificate ca_cert = make_ca_cert(rng, ca_key, now, later);
+
+ const std::string ca_password = "sekrit";
+
+ save_pair("ca", ca_password, ca_cert, ca_key, rng);
+
+ X509_CA ca(ca_cert, ca_key);
+
+ RSA_PrivateKey httpd_key(rng, 1536);
+ X509_Certificate httpd_cert = ca.sign_request(
+ make_server_cert_req(httpd_key, "www.randombit.net", rng),
+ rng, now, later);
+
+ save_pair("httpd", "", httpd_cert, httpd_key, rng);
+
+ RSA_PrivateKey bugzilla_key(rng, 1536);
+ X509_Certificate bugzilla_cert = ca.sign_request(
+ make_server_cert_req(bugzilla_key, "bugs.randombit.net", rng),
+ rng, now, later);
+
+ save_pair("bugzilla", "", bugzilla_cert, bugzilla_key, rng);
+
+ RSA_PrivateKey postfix_key(rng, 1536);
+ X509_Certificate postfix_cert = ca.sign_request(
+ make_server_cert_req(postfix_key, "mail.randombit.net", rng),
+ rng, now, later);
+
+ save_pair("postfix", "", postfix_cert, postfix_key, rng);
+
+ RSA_PrivateKey dovecot_key(rng, 1536);
+ X509_Certificate dovecot_cert = ca.sign_request(
+ make_server_cert_req(dovecot_key, "imap.randombit.net", rng),
+ rng, now, later);
+
+ save_pair("dovecot", "", dovecot_cert, dovecot_key, rng);
+ }
diff --git a/doc/license.txt b/doc/license.txt
index 4c3fc1999..9d1067cc1 100644
--- a/doc/license.txt
+++ b/doc/license.txt
@@ -1,3 +1,5 @@
+Botan (http://botan.randombit.net/) is distributed under these terms:
+
Copyright (C) 1999-2009 Jack Lloyd
2001 Peter J Jones
2004-2007 Justin Karneges
@@ -12,10 +14,11 @@ Copyright (C) 1999-2009 Jack Lloyd
2007 Manuel Hartl
2007 Christoph Ludwig
2007 Patrick Sona
+All rights reserved.
-Redistribution and use in source and binary forms, for any use, with
-or without modification, of Botan (http://botan.randombit.net/) is
-permitted provided that the following conditions are met:
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
@@ -27,13 +30,11 @@ documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
-ARE DISCLAIMED.
-
-IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/doc/log.txt b/doc/log.txt
index 831757d63..345e91d71 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -1,7 +1,29 @@
-* 1.8.5-rc1, 2009-07-20
+* 1.9.0-pre, 2009-??-??
+ - Add support for parallel invocation of block ciphers where possible
+ - Add SSE2 implementation of Serpent
+ - Add Rivest's package transform (an all or nothing transform)
+ - Minor speedups to the Turing key schedule
+
+* 1.8.7-pre, 2009-??-??
+ - Fix processing multiple messages in XTS mode
+ - Add --no-autoload option to configure.py, for minimized builds
+
+* 1.8.6, 2009-08-13
+ - Add Cryptobox, a set of simple password-based encryption routines
+ - Only read world-readable files when walking /proc for entropy
+ - Fix building with TR1 disabled
+ - Fix x86 bswap support for Visual C++
+ - Fixes for compilation under Sun C++
+ - Add support for Dragonfly BSD (contributed by Patrick Georgi)
+ - Add support for the Open64 C++ compiler
+ - Build fixes for MIPS systems running Linux
+ - Minor changes to license, now equivalent to the FreeBSD/NetBSD license
+
+* 1.8.5, 2009-07-23
- Change configure.py to work on stock Python 2.4
- Avoid a crash in Skein_512::add_data processing a zero-length input
+ - Small build fixes for SPARC, ARM, and HP-PA processors
- The test suite now returns an error code from main() if any tests failed
* 1.8.4, 2009-07-12
diff --git a/configure.pl b/doc/scripts/configure.pl
index 85b1508b8..6cf43e5e6 100755
--- a/configure.pl
+++ b/doc/scripts/configure.pl
@@ -13,11 +13,11 @@ use Sys::Hostname;
my $MAJOR_VERSION = 1;
my $MINOR_VERSION = 8;
-my $PATCH_VERSION = 5;
+my $PATCH_VERSION = 7;
-my $VERSION_SUFFIX = '-rc1';
+my $VERSION_SUFFIX = '-pre';
-my $SO_PATCH_VERSION = 5;
+my $SO_PATCH_VERSION = 7;
my $VERSION_STRING = "$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION$VERSION_SUFFIX";
my $SO_VERSION_STRING = "$MAJOR_VERSION.$MINOR_VERSION.$SO_PATCH_VERSION$VERSION_SUFFIX";
@@ -40,10 +40,6 @@ my $TRACING = 0;
##################################################
my $config = {};
-print STDERR "* WARNING\n" .
- "* $0 is deprecated; consider trying configure.py instead\n" .
- "* If it works, great. If not, file a bug and continue using $0\n*\n";
-
main();
exit;
@@ -60,12 +56,18 @@ sub exec_uname {
return '';
}
+sub deprecation_warning {
+ warning("$0 is deprecated; migration to ./configure.py strongly recommended");
+}
+
##################################################
# Main Driver #
##################################################
sub main {
my $base_dir = where_am_i();
+ deprecation_warning();
+
$$config{'uname'} = exec_uname();
$$config{'base-dir'} = $base_dir;
@@ -161,8 +163,7 @@ sub main {
File::Spec->catdir($$config{'build_dir'}, 'include', 'botan'),
'mp_bits' => find_mp_bits($config),
- 'mod_libs' =>
- [ using_libs($os, sort keys %{$$config{'modules'}}) ],
+ 'mod_libs' => [ using_libs($config) ],
'sources' => { },
'includes' => { },
@@ -202,6 +203,8 @@ sub main {
generate_makefile($config);
copy_include_files($config);
+
+ deprecation_warning();
}
sub where_am_i {
@@ -509,8 +512,6 @@ sub module_runs_on {
sub scan_modules {
my ($config) = @_;
- my %dep_mods = ();
-
foreach my $mod (sort keys %MODULES) {
my %modinfo = %{ $MODULES{$mod} };
@@ -519,9 +520,11 @@ sub scan_modules {
next unless(module_runs_on($config, \%modinfo, $mod, 0));
if($modinfo{'load_on'} eq 'auto' or
+ $modinfo{'load_on'} eq 'always' or
($modinfo{'load_on'} eq 'asm_ok' and $$config{'asm_ok'})) {
- $$config{'modules'}{$mod} = 1;
+ my %maybe_load = ();
+ my $all_deps_found = 1;
LINE: foreach (@{$modinfo{'requires'}}) {
for my $req_mod (split(/\|/, $_)) {
@@ -530,18 +533,19 @@ sub scan_modules {
next if(defined($$config{'modules'}{$req_mod}) && $$config{'modules'}{$req_mod} < 0);
next unless(module_runs_on($config, $MODULES{$req_mod}, $req_mod, 0));
- $dep_mods{$req_mod} = 1;
+ $maybe_load{$req_mod} = 1;
next LINE;
}
+ $all_deps_found = 0;
}
- next;
+ if($all_deps_found) {
+ foreach my $depmod (keys %maybe_load)
+ { $$config{'modules'}{$depmod} = 1; }
+ $$config{'modules'}{$mod} = 1;
+ }
}
}
-
- foreach my $mod (sort keys %dep_mods) {
- $$config{'modules'}{$mod} = 1;
- }
}
sub print_enabled_modules {
@@ -939,24 +943,30 @@ sub mach_opt {
# #
##################################################
sub using_libs {
- my ($os,@using) = @_;
+ my ($config) = @_;
+
+ my $os = $$config{'os'};
my %libs;
- foreach my $mod (@using) {
+ foreach my $mod (sort keys %{$$config{'modules'}}) {
+ next if ${$$config{'modules'}}{$mod} < 0;
+
my %MOD_LIBS = %{ $MODULES{$mod}{'libs'} };
- foreach my $mod_os (keys %MOD_LIBS) {
+
+ foreach my $mod_os (keys %MOD_LIBS)
+ {
next if($mod_os =~ /^all!$os$/);
next if($mod_os =~ /^all!$os,/);
- next if($mod_os =~ /^all!.*,${os}$/);
+ #next if($mod_os =~ /^all!.*,${os}$/);
next if($mod_os =~ /^all!.*,$os,.*/);
next unless($mod_os eq $os or ($mod_os =~ /^all.*/));
my @liblist = split(/,/, $MOD_LIBS{$mod_os});
foreach my $lib (@liblist) { $libs{$lib} = 1; }
- }
}
+ }
return sort keys %libs;
- }
+}
sub libs {
my ($prefix,$suffix,@libs) = @_;
@@ -1270,6 +1280,7 @@ sub load_modules {
if($arch ne $submodel) {
$submodel = uc $submodel;
$submodel =~ tr/-/_/;
+ $submodel =~ tr/.//;
push @macro_list, "#define BOTAN_TARGET_CPU_IS_$submodel";
}
diff --git a/doc/scripts/dist.sh b/doc/scripts/dist.sh
index d66066173..0062d43bf 100755
--- a/doc/scripts/dist.sh
+++ b/doc/scripts/dist.sh
@@ -5,8 +5,8 @@
SELECTOR=h:net.randombit.botan
KEY_ID=EFBADFBC
-MTN_DB=~/var/mtn/botan.mtn
-WEB_DIR=~/var/www
+MTN_DB=/storage/mtn/botan.mtn
+WEB_DIR=~/projects/www
DIST_DIR=~/Botan-dist
# You shouldn't have to change anything after this
@@ -15,7 +15,7 @@ cd $DIST_DIR
mtn -d $MTN_DB checkout -r $SELECTOR Botan
-VERSION=$(Botan/configure.pl --version | sed 's/Botan //')
+VERSION=$(Botan/configure.py --version)
mv Botan Botan-$VERSION
diff --git a/readme.txt b/readme.txt
index 8b9c96531..4936116f0 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
-Botan 1.8.5-rc1 2009-07-20
+Botan 1.9.0-pre 2009-??-??
Botan is a C++ class library for performing a wide variety of
cryptographic operations.
diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp
index 71bd26827..e891dc5cd 100644
--- a/src/algo_factory/algo_factory.cpp
+++ b/src/algo_factory/algo_factory.cpp
@@ -1,6 +1,6 @@
/*
-Algorithm Factory
-(C) 2008 Jack Lloyd
+* Algorithm Factory
+* (C) 2008 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
diff --git a/src/alloc/alloc_mmap/info.txt b/src/alloc/alloc_mmap/info.txt
index d8c766d55..65d9b2977 100644
--- a/src/alloc/alloc_mmap/info.txt
+++ b/src/alloc/alloc_mmap/info.txt
@@ -13,6 +13,7 @@ mmap_mem.h
<os>
linux
freebsd
+dragonfly
openbsd
netbsd
solaris
diff --git a/src/aont/info.txt b/src/aont/info.txt
new file mode 100644
index 000000000..a0387f358
--- /dev/null
+++ b/src/aont/info.txt
@@ -0,0 +1,17 @@
+realname "All or Nothing Transforms"
+
+define PACKAGE_TRANSFORM
+
+load_on auto
+
+<add>
+package.cpp
+package.h
+</add>
+
+<requires>
+block
+ctr
+rng
+filters
+</requires>
diff --git a/src/aont/package.cpp b/src/aont/package.cpp
new file mode 100644
index 000000000..6c6b56865
--- /dev/null
+++ b/src/aont/package.cpp
@@ -0,0 +1,128 @@
+/*
+* Rivest's Package Tranform
+*
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/package.h>
+#include <botan/pipe.h>
+#include <botan/ctr.h>
+#include <botan/loadstor.h>
+#include <botan/xor_buf.h>
+
+namespace Botan {
+
+namespace AllOrNothingTransform {
+
+void package(RandomNumberGenerator& rng,
+ BlockCipher* cipher,
+ const byte input[], u32bit input_len,
+ byte output[])
+ {
+ if(!cipher->valid_keylength(cipher->BLOCK_SIZE))
+ throw Invalid_Argument("AONT::package: Invalid cipher");
+
+ // The all-zero string which is used both as the CTR IV and as K0
+ const std::string all_zeros(cipher->BLOCK_SIZE*2, '0');
+
+ SymmetricKey package_key(rng, cipher->BLOCK_SIZE);
+
+ // takes ownership of cipher object
+ Keyed_Filter* ctr_mode = new CTR_BE(cipher,
+ package_key,
+ InitializationVector(all_zeros));
+
+ Pipe pipe(ctr_mode);
+
+ pipe.process_msg(input, input_len);
+ pipe.read(output, pipe.remaining());
+
+ // Set K0 (the all zero key)
+ cipher->set_key(SymmetricKey(all_zeros));
+
+ SecureVector<byte> buf(cipher->BLOCK_SIZE);
+
+ const u32bit blocks =
+ (input_len + cipher->BLOCK_SIZE - 1) / cipher->BLOCK_SIZE;
+
+ byte* final_block = output + input_len;
+ clear_mem(final_block, cipher->BLOCK_SIZE);
+
+ // XOR the hash blocks into the final block
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit left = std::min<u32bit>(cipher->BLOCK_SIZE,
+ input_len - cipher->BLOCK_SIZE * i);
+
+ buf.clear();
+ copy_mem(&buf[0], output + cipher->BLOCK_SIZE * i, left);
+
+ for(u32bit j = 0; j != 4; ++j)
+ buf[cipher->BLOCK_SIZE - 1 - j] ^= get_byte(3-j, i);
+
+ cipher->encrypt(buf);
+
+ xor_buf(final_block, buf, cipher->BLOCK_SIZE);
+ }
+
+ // XOR the random package key into the final block
+ xor_buf(final_block, package_key.begin(), cipher->BLOCK_SIZE);
+ }
+
+void unpackage(BlockCipher* cipher,
+ const byte input[], u32bit input_len,
+ byte output[])
+ {
+ if(!cipher->valid_keylength(cipher->BLOCK_SIZE))
+ throw Invalid_Argument("AONT::unpackage: Invalid cipher");
+
+ if(input_len < cipher->BLOCK_SIZE)
+ throw Invalid_Argument("AONT::unpackage: Input too short");
+
+ // The all-zero string which is used both as the CTR IV and as K0
+ const std::string all_zeros(cipher->BLOCK_SIZE*2, '0');
+
+ cipher->set_key(SymmetricKey(all_zeros));
+
+ SecureVector<byte> package_key(cipher->BLOCK_SIZE);
+ SecureVector<byte> buf(cipher->BLOCK_SIZE);
+
+ // Copy the package key (masked with the block hashes)
+ copy_mem(&package_key[0],
+ input + (input_len - cipher->BLOCK_SIZE),
+ cipher->BLOCK_SIZE);
+
+ const u32bit blocks = ((input_len - 1) / cipher->BLOCK_SIZE);
+
+ // XOR the blocks into the package key bits
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit left = std::min<u32bit>(cipher->BLOCK_SIZE,
+ input_len - cipher->BLOCK_SIZE * (i+1));
+
+ buf.clear();
+ copy_mem(&buf[0], input + cipher->BLOCK_SIZE * i, left);
+
+ for(u32bit j = 0; j != 4; ++j)
+ buf[cipher->BLOCK_SIZE - 1 - j] ^= get_byte(3-j, i);
+
+ cipher->encrypt(buf);
+
+ xor_buf(&package_key[0], buf, cipher->BLOCK_SIZE);
+ }
+
+ // takes ownership of cipher object
+ Pipe pipe(new CTR_BE(cipher,
+ SymmetricKey(package_key),
+ InitializationVector(all_zeros)));
+
+ pipe.process_msg(input, input_len - cipher->BLOCK_SIZE);
+
+ pipe.read(output, pipe.remaining());
+ }
+
+}
+
+}
diff --git a/src/aont/package.h b/src/aont/package.h
new file mode 100644
index 000000000..35d2a23fc
--- /dev/null
+++ b/src/aont/package.h
@@ -0,0 +1,45 @@
+/*
+* Rivest's Package Tranform
+*
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/block_cipher.h>
+#include <botan/rng.h>
+
+namespace Botan {
+
+namespace AllOrNothingTransform {
+
+/**
+* Rivest's Package Tranform
+* @arg rng the random number generator to use
+* @arg cipher the block cipher to use
+* @arg input the input data buffer
+* @arg input_len the length of the input data in bytes
+* @arg output the output data buffer (must be at least
+* input_len + cipher->BLOCK_SIZE bytes long)
+*/
+void package(RandomNumberGenerator& rng,
+ BlockCipher* cipher,
+ const byte input[], u32bit input_len,
+ byte output[]);
+
+/**
+* Rivest's Package Tranform (Inversion)
+* @arg rng the random number generator to use
+* @arg cipher the block cipher to use
+* @arg input the input data buffer
+* @arg input_len the length of the input data in bytes
+* @arg output the output data buffer (must be at least
+* input_len - cipher->BLOCK_SIZE bytes long)
+*/
+void unpackage(BlockCipher* cipher,
+ const byte input[], u32bit input_len,
+ byte output[]);
+
+}
+
+}
diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp
index d30e831b9..3bbc1f883 100644
--- a/src/benchmark/benchmark.cpp
+++ b/src/benchmark/benchmark.cpp
@@ -57,8 +57,7 @@ bench_block_cipher(BlockCipher* block_cipher,
while(nanoseconds_used < nanoseconds_max)
{
- for(u32bit i = 0; i != in_blocks; ++i)
- block_cipher->encrypt(buf + block_cipher->BLOCK_SIZE * i);
+ block_cipher->encrypt_n(buf, buf, in_blocks);
++reps;
nanoseconds_used = timer.clock() - start;
@@ -140,7 +139,7 @@ algorithm_benchmark(const std::string& name,
{
const std::string provider = providers[i];
- std::pair<u64bit, u64bit> results = std::make_pair(0, 0);
+ std::pair<u64bit, u64bit> results(0, 0);
if(const BlockCipher* proto =
af.prototype_block_cipher(name, provider))
diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp
index 9072b507b..34698ae7f 100644
--- a/src/block/aes/aes.cpp
+++ b/src/block/aes/aes.cpp
@@ -1,6 +1,6 @@
/**
* AES
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -13,163 +13,175 @@ namespace Botan {
/**
* AES Encryption
*/
-void AES::enc(const byte in[], byte out[]) const
+void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
const u32bit* TE0 = TE;
const u32bit* TE1 = TE + 256;
const u32bit* TE2 = TE + 512;
const u32bit* TE3 = TE + 768;
- u32bit T0 = load_be<u32bit>(in, 0) ^ EK[0];
- u32bit T1 = load_be<u32bit>(in, 1) ^ EK[1];
- u32bit T2 = load_be<u32bit>(in, 2) ^ EK[2];
- u32bit T3 = load_be<u32bit>(in, 3) ^ EK[3];
-
- u32bit B0, B1, B2, B3;
- B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^
- TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4];
- B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^
- TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ EK[5];
- B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^
- TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ EK[6];
- B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^
- TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ EK[7];
-
- for(u32bit j = 2; j != ROUNDS; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u32bit K0 = EK[4*j];
- const u32bit K1 = EK[4*j+1];
- const u32bit K2 = EK[4*j+2];
- const u32bit K3 = EK[4*j+3];
-
- T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(1, B1)] ^
- TE2[get_byte(2, B2)] ^ TE3[get_byte(3, B3)] ^ K0;
- T1 = TE0[get_byte(0, B1)] ^ TE1[get_byte(1, B2)] ^
- TE2[get_byte(2, B3)] ^ TE3[get_byte(3, B0)] ^ K1;
- T2 = TE0[get_byte(0, B2)] ^ TE1[get_byte(1, B3)] ^
- TE2[get_byte(2, B0)] ^ TE3[get_byte(3, B1)] ^ K2;
- T3 = TE0[get_byte(0, B3)] ^ TE1[get_byte(1, B0)] ^
- TE2[get_byte(2, B1)] ^ TE3[get_byte(3, B2)] ^ K3;
-
- const u32bit K4 = EK[4*(j+1)+0];
- const u32bit K5 = EK[4*(j+1)+1];
- const u32bit K6 = EK[4*(j+1)+2];
- const u32bit K7 = EK[4*(j+1)+3];
+ u32bit T0 = load_be<u32bit>(in, 0) ^ EK[0];
+ u32bit T1 = load_be<u32bit>(in, 1) ^ EK[1];
+ u32bit T2 = load_be<u32bit>(in, 2) ^ EK[2];
+ u32bit T3 = load_be<u32bit>(in, 3) ^ EK[3];
+ u32bit B0, B1, B2, B3;
B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^
- TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ K4;
+ TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4];
B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^
- TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ K5;
+ TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ EK[5];
B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^
- TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ K6;
+ TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ EK[6];
B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^
- TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ K7;
- }
+ TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ EK[7];
+
+ for(u32bit j = 2; j != ROUNDS; j += 2)
+ {
+ const u32bit K0 = EK[4*j];
+ const u32bit K1 = EK[4*j+1];
+ const u32bit K2 = EK[4*j+2];
+ const u32bit K3 = EK[4*j+3];
+
+ T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(1, B1)] ^
+ TE2[get_byte(2, B2)] ^ TE3[get_byte(3, B3)] ^ K0;
+ T1 = TE0[get_byte(0, B1)] ^ TE1[get_byte(1, B2)] ^
+ TE2[get_byte(2, B3)] ^ TE3[get_byte(3, B0)] ^ K1;
+ T2 = TE0[get_byte(0, B2)] ^ TE1[get_byte(1, B3)] ^
+ TE2[get_byte(2, B0)] ^ TE3[get_byte(3, B1)] ^ K2;
+ T3 = TE0[get_byte(0, B3)] ^ TE1[get_byte(1, B0)] ^
+ TE2[get_byte(2, B1)] ^ TE3[get_byte(3, B2)] ^ K3;
+
+ const u32bit K4 = EK[4*(j+1)+0];
+ const u32bit K5 = EK[4*(j+1)+1];
+ const u32bit K6 = EK[4*(j+1)+2];
+ const u32bit K7 = EK[4*(j+1)+3];
- /*
- Joseph Bonneau and Ilya Mironov's paper
- <a href = "http://icme2007.org/users/mironov/papers/aes-timing.pdf">
- Cache-Collision Timing Attacks Against AES</a> describes an attack
- that can recover AES keys with as few as 2<sup>13</sup> samples.
-
- """In addition to OpenSSL v. 0.9.8.(a), which was used in our
- experiments, the AES implementations of Crypto++ 5.2.1 and
- LibTomCrypt 1.09 use the original Rijndael C implementation with
- very few changes and are highly vulnerable. The AES implementations
- in libgcrypt v. 1.2.2 and Botan v. 1.4.2 are also vulnerable, but
- use a smaller byte-wide final table which lessens the effectiveness
- of the attacks."""
- */
- out[ 0] = SE[get_byte(0, B0)] ^ ME[0];
- out[ 1] = SE[get_byte(1, B1)] ^ ME[1];
- out[ 2] = SE[get_byte(2, B2)] ^ ME[2];
- out[ 3] = SE[get_byte(3, B3)] ^ ME[3];
- out[ 4] = SE[get_byte(0, B1)] ^ ME[4];
- out[ 5] = SE[get_byte(1, B2)] ^ ME[5];
- out[ 6] = SE[get_byte(2, B3)] ^ ME[6];
- out[ 7] = SE[get_byte(3, B0)] ^ ME[7];
- out[ 8] = SE[get_byte(0, B2)] ^ ME[8];
- out[ 9] = SE[get_byte(1, B3)] ^ ME[9];
- out[10] = SE[get_byte(2, B0)] ^ ME[10];
- out[11] = SE[get_byte(3, B1)] ^ ME[11];
- out[12] = SE[get_byte(0, B3)] ^ ME[12];
- out[13] = SE[get_byte(1, B0)] ^ ME[13];
- out[14] = SE[get_byte(2, B1)] ^ ME[14];
- out[15] = SE[get_byte(3, B2)] ^ ME[15];
+ B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^
+ TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ K4;
+ B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^
+ TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ K5;
+ B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^
+ TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ K6;
+ B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^
+ TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ K7;
+ }
+
+ /*
+ Joseph Bonneau and Ilya Mironov's paper
+ <a href = "http://icme2007.org/users/mironov/papers/aes-timing.pdf">
+ Cache-Collision Timing Attacks Against AES</a> describes an attack
+ that can recover AES keys with as few as 2<sup>13</sup> samples.
+
+ """In addition to OpenSSL v. 0.9.8.(a), which was used in our
+ experiments, the AES implementations of Crypto++ 5.2.1 and
+ LibTomCrypt 1.09 use the original Rijndael C implementation with
+ very few changes and are highly vulnerable. The AES implementations
+ in libgcrypt v. 1.2.2 and Botan v. 1.4.2 are also vulnerable, but
+ use a smaller byte-wide final table which lessens the effectiveness
+ of the attacks."""
+ */
+ out[ 0] = SE[get_byte(0, B0)] ^ ME[0];
+ out[ 1] = SE[get_byte(1, B1)] ^ ME[1];
+ out[ 2] = SE[get_byte(2, B2)] ^ ME[2];
+ out[ 3] = SE[get_byte(3, B3)] ^ ME[3];
+ out[ 4] = SE[get_byte(0, B1)] ^ ME[4];
+ out[ 5] = SE[get_byte(1, B2)] ^ ME[5];
+ out[ 6] = SE[get_byte(2, B3)] ^ ME[6];
+ out[ 7] = SE[get_byte(3, B0)] ^ ME[7];
+ out[ 8] = SE[get_byte(0, B2)] ^ ME[8];
+ out[ 9] = SE[get_byte(1, B3)] ^ ME[9];
+ out[10] = SE[get_byte(2, B0)] ^ ME[10];
+ out[11] = SE[get_byte(3, B1)] ^ ME[11];
+ out[12] = SE[get_byte(0, B3)] ^ ME[12];
+ out[13] = SE[get_byte(1, B0)] ^ ME[13];
+ out[14] = SE[get_byte(2, B1)] ^ ME[14];
+ out[15] = SE[get_byte(3, B2)] ^ ME[15];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/**
* AES Decryption
*/
-void AES::dec(const byte in[], byte out[]) const
+void AES::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
const u32bit* TD0 = TD;
const u32bit* TD1 = TD + 256;
const u32bit* TD2 = TD + 512;
const u32bit* TD3 = TD + 768;
- u32bit T0 = load_be<u32bit>(in, 0) ^ DK[0];
- u32bit T1 = load_be<u32bit>(in, 1) ^ DK[1];
- u32bit T2 = load_be<u32bit>(in, 2) ^ DK[2];
- u32bit T3 = load_be<u32bit>(in, 3) ^ DK[3];
-
- u32bit B0, B1, B2, B3;
- B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^
- TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ DK[4];
- B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^
- TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ DK[5];
- B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^
- TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ DK[6];
- B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^
- TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ DK[7];
-
- for(u32bit j = 2; j != ROUNDS; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u32bit K0 = DK[4*j+0];
- const u32bit K1 = DK[4*j+1];
- const u32bit K2 = DK[4*j+2];
- const u32bit K3 = DK[4*j+3];
-
- T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(1, B3)] ^
- TD2[get_byte(2, B2)] ^ TD3[get_byte(3, B1)] ^ K0;
- T1 = TD0[get_byte(0, B1)] ^ TD1[get_byte(1, B0)] ^
- TD2[get_byte(2, B3)] ^ TD3[get_byte(3, B2)] ^ K1;
- T2 = TD0[get_byte(0, B2)] ^ TD1[get_byte(1, B1)] ^
- TD2[get_byte(2, B0)] ^ TD3[get_byte(3, B3)] ^ K2;
- T3 = TD0[get_byte(0, B3)] ^ TD1[get_byte(1, B2)] ^
- TD2[get_byte(2, B1)] ^ TD3[get_byte(3, B0)] ^ K3;
-
- const u32bit K4 = DK[4*(j+1)+0];
- const u32bit K5 = DK[4*(j+1)+1];
- const u32bit K6 = DK[4*(j+1)+2];
- const u32bit K7 = DK[4*(j+1)+3];
+ u32bit T0 = load_be<u32bit>(in, 0) ^ DK[0];
+ u32bit T1 = load_be<u32bit>(in, 1) ^ DK[1];
+ u32bit T2 = load_be<u32bit>(in, 2) ^ DK[2];
+ u32bit T3 = load_be<u32bit>(in, 3) ^ DK[3];
+ u32bit B0, B1, B2, B3;
B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^
- TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ K4;
+ TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ DK[4];
B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^
- TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ K5;
+ TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ DK[5];
B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^
- TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ K6;
+ TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ DK[6];
B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^
- TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ K7;
- }
+ TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ DK[7];
+
+ for(u32bit j = 2; j != ROUNDS; j += 2)
+ {
+ const u32bit K0 = DK[4*j+0];
+ const u32bit K1 = DK[4*j+1];
+ const u32bit K2 = DK[4*j+2];
+ const u32bit K3 = DK[4*j+3];
+
+ T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(1, B3)] ^
+ TD2[get_byte(2, B2)] ^ TD3[get_byte(3, B1)] ^ K0;
+ T1 = TD0[get_byte(0, B1)] ^ TD1[get_byte(1, B0)] ^
+ TD2[get_byte(2, B3)] ^ TD3[get_byte(3, B2)] ^ K1;
+ T2 = TD0[get_byte(0, B2)] ^ TD1[get_byte(1, B1)] ^
+ TD2[get_byte(2, B0)] ^ TD3[get_byte(3, B3)] ^ K2;
+ T3 = TD0[get_byte(0, B3)] ^ TD1[get_byte(1, B2)] ^
+ TD2[get_byte(2, B1)] ^ TD3[get_byte(3, B0)] ^ K3;
+
+ const u32bit K4 = DK[4*(j+1)+0];
+ const u32bit K5 = DK[4*(j+1)+1];
+ const u32bit K6 = DK[4*(j+1)+2];
+ const u32bit K7 = DK[4*(j+1)+3];
- out[ 0] = SD[get_byte(0, B0)] ^ MD[0];
- out[ 1] = SD[get_byte(1, B3)] ^ MD[1];
- out[ 2] = SD[get_byte(2, B2)] ^ MD[2];
- out[ 3] = SD[get_byte(3, B1)] ^ MD[3];
- out[ 4] = SD[get_byte(0, B1)] ^ MD[4];
- out[ 5] = SD[get_byte(1, B0)] ^ MD[5];
- out[ 6] = SD[get_byte(2, B3)] ^ MD[6];
- out[ 7] = SD[get_byte(3, B2)] ^ MD[7];
- out[ 8] = SD[get_byte(0, B2)] ^ MD[8];
- out[ 9] = SD[get_byte(1, B1)] ^ MD[9];
- out[10] = SD[get_byte(2, B0)] ^ MD[10];
- out[11] = SD[get_byte(3, B3)] ^ MD[11];
- out[12] = SD[get_byte(0, B3)] ^ MD[12];
- out[13] = SD[get_byte(1, B2)] ^ MD[13];
- out[14] = SD[get_byte(2, B1)] ^ MD[14];
- out[15] = SD[get_byte(3, B0)] ^ MD[15];
+ B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^
+ TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ K4;
+ B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^
+ TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ K5;
+ B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^
+ TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ K6;
+ B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^
+ TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ K7;
+ }
+
+ out[ 0] = SD[get_byte(0, B0)] ^ MD[0];
+ out[ 1] = SD[get_byte(1, B3)] ^ MD[1];
+ out[ 2] = SD[get_byte(2, B2)] ^ MD[2];
+ out[ 3] = SD[get_byte(3, B1)] ^ MD[3];
+ out[ 4] = SD[get_byte(0, B1)] ^ MD[4];
+ out[ 5] = SD[get_byte(1, B0)] ^ MD[5];
+ out[ 6] = SD[get_byte(2, B3)] ^ MD[6];
+ out[ 7] = SD[get_byte(3, B2)] ^ MD[7];
+ out[ 8] = SD[get_byte(0, B2)] ^ MD[8];
+ out[ 9] = SD[get_byte(1, B1)] ^ MD[9];
+ out[10] = SD[get_byte(2, B0)] ^ MD[10];
+ out[11] = SD[get_byte(3, B3)] ^ MD[11];
+ out[12] = SD[get_byte(0, B3)] ^ MD[12];
+ out[13] = SD[get_byte(1, B2)] ^ MD[13];
+ out[14] = SD[get_byte(2, B1)] ^ MD[14];
+ out[15] = SD[get_byte(3, B0)] ^ MD[15];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/**
diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h
index 05e2e3123..768bb09e7 100644
--- a/src/block/aes/aes.h
+++ b/src/block/aes/aes.h
@@ -1,6 +1,6 @@
/**
* AES
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -18,14 +18,16 @@ namespace Botan {
class BOTAN_DLL AES : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "AES"; }
BlockCipher* clone() const { return new AES; }
+
AES() : BlockCipher(16, 16, 32, 8) { ROUNDS = 14; }
AES(u32bit);
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static u32bit S(u32bit);
diff --git a/src/block/block_cipher.h b/src/block/block_cipher.h
index 01c45af04..a27609171 100644
--- a/src/block/block_cipher.h
+++ b/src/block/block_cipher.h
@@ -1,6 +1,6 @@
/**
* Block Cipher Base Class
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -45,7 +45,8 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* @param out The byte array designated to hold the encrypted block.
* Must be of length BLOCK_SIZE.
*/
- void encrypt(const byte in[], byte out[]) const { enc(in, out); }
+ void encrypt(const byte in[], byte out[]) const
+ { encrypt_n(in, out, 1); }
/**
* Decrypt a block.
@@ -54,7 +55,8 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* @param out The byte array designated to hold the decrypted block.
* Must be of length BLOCK_SIZE.
*/
- void decrypt(const byte in[], byte out[]) const { dec(in, out); }
+ void decrypt(const byte in[], byte out[]) const
+ { decrypt_n(in, out, 1); }
/**
* Encrypt a block.
@@ -62,7 +64,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* Must be of length BLOCK_SIZE. Will hold the result when the function
* has finished.
*/
- void encrypt(byte block[]) const { enc(block, block); }
+ void encrypt(byte block[]) const { encrypt_n(block, block, 1); }
/**
* Decrypt a block.
@@ -70,7 +72,12 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
* Must be of length BLOCK_SIZE. Will hold the result when the function
* has finished.
*/
- void decrypt(byte block[]) const { dec(block, block); }
+ void decrypt(byte block[]) const { decrypt_n(block, block, 1); }
+
+ virtual void encrypt_n(const byte in[], byte out[],
+ u32bit blocks) const = 0;
+ virtual void decrypt_n(const byte in[], byte out[],
+ u32bit blocks) const = 0;
/**
* Get a new object representing the same algorithm as *this
@@ -90,9 +97,6 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm
BLOCK_SIZE(block_size) {}
virtual ~BlockCipher() {}
- private:
- virtual void enc(const byte[], byte[]) const = 0;
- virtual void dec(const byte[], byte[]) const = 0;
};
}
diff --git a/src/block/blowfish/blowfish.cpp b/src/block/blowfish/blowfish.cpp
index b0599d6c5..312603c3a 100644
--- a/src/block/blowfish/blowfish.cpp
+++ b/src/block/blowfish/blowfish.cpp
@@ -1,6 +1,6 @@
/*
* Blowfish
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -13,59 +13,71 @@ namespace Botan {
/*
* Blowfish Encryption
*/
-void Blowfish::enc(const byte in[], byte out[]) const
+void Blowfish::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
const u32bit* S1 = S + 0;
const u32bit* S2 = S + 256;
const u32bit* S3 = S + 512;
const u32bit* S4 = S + 768;
- u32bit L = load_be<u32bit>(in, 0);
- u32bit R = load_be<u32bit>(in, 1);
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- L ^= P[j];
- R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^
- S3[get_byte(2, L)]) + S4[get_byte(3, L)];
+ u32bit L = load_be<u32bit>(in, 0);
+ u32bit R = load_be<u32bit>(in, 1);
- R ^= P[j+1];
- L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^
- S3[get_byte(2, R)]) + S4[get_byte(3, R)];
- }
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ L ^= P[j];
+ R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^
+ S3[get_byte(2, L)]) + S4[get_byte(3, L)];
- L ^= P[16]; R ^= P[17];
+ R ^= P[j+1];
+ L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^
+ S3[get_byte(2, R)]) + S4[get_byte(3, R)];
+ }
+
+ L ^= P[16]; R ^= P[17];
- store_be(out, R, L);
+ store_be(out, R, L);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Blowfish Decryption
*/
-void Blowfish::dec(const byte in[], byte out[]) const
+void Blowfish::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
const u32bit* S1 = S + 0;
const u32bit* S2 = S + 256;
const u32bit* S3 = S + 512;
const u32bit* S4 = S + 768;
- u32bit L = load_be<u32bit>(in, 0);
- u32bit R = load_be<u32bit>(in, 1);
-
- for(u32bit j = 17; j != 1; j -= 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- L ^= P[j];
- R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^
- S3[get_byte(2, L)]) + S4[get_byte(3, L)];
+ u32bit L = load_be<u32bit>(in, 0);
+ u32bit R = load_be<u32bit>(in, 1);
- R ^= P[j-1];
- L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^
- S3[get_byte(2, R)]) + S4[get_byte(3, R)];
- }
+ for(u32bit j = 17; j != 1; j -= 2)
+ {
+ L ^= P[j];
+ R ^= ((S1[get_byte(0, L)] + S2[get_byte(1, L)]) ^
+ S3[get_byte(2, L)]) + S4[get_byte(3, L)];
- L ^= P[1]; R ^= P[0];
+ R ^= P[j-1];
+ L ^= ((S1[get_byte(0, R)] + S2[get_byte(1, R)]) ^
+ S3[get_byte(2, R)]) + S4[get_byte(3, R)];
+ }
+
+ L ^= P[1]; R ^= P[0];
- store_be(out, R, L);
+ store_be(out, R, L);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/blowfish/blowfish.h b/src/block/blowfish/blowfish.h
index f0f26418d..345c1ce49 100644
--- a/src/block/blowfish/blowfish.h
+++ b/src/block/blowfish/blowfish.h
@@ -1,6 +1,6 @@
/*
* Blowfish
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Blowfish : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Blowfish"; }
BlockCipher* clone() const { return new Blowfish; }
+
Blowfish() : BlockCipher(8, 1, 56) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
void generate_sbox(u32bit[], u32bit, u32bit&, u32bit&) const;
diff --git a/src/block/cast/cast128.cpp b/src/block/cast/cast128.cpp
index 046638ab9..887dcf994 100644
--- a/src/block/cast/cast128.cpp
+++ b/src/block/cast/cast128.cpp
@@ -48,57 +48,69 @@ inline void R3(u32bit& L, u32bit R, u32bit MK, u32bit RK)
/*
* CAST-128 Encryption
*/
-void CAST_128::enc(const byte in[], byte out[]) const
+void CAST_128::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0);
- u32bit R = load_be<u32bit>(in, 1);
-
- R1(L, R, MK[ 0], RK[ 0]);
- R2(R, L, MK[ 1], RK[ 1]);
- R3(L, R, MK[ 2], RK[ 2]);
- R1(R, L, MK[ 3], RK[ 3]);
- R2(L, R, MK[ 4], RK[ 4]);
- R3(R, L, MK[ 5], RK[ 5]);
- R1(L, R, MK[ 6], RK[ 6]);
- R2(R, L, MK[ 7], RK[ 7]);
- R3(L, R, MK[ 8], RK[ 8]);
- R1(R, L, MK[ 9], RK[ 9]);
- R2(L, R, MK[10], RK[10]);
- R3(R, L, MK[11], RK[11]);
- R1(L, R, MK[12], RK[12]);
- R2(R, L, MK[13], RK[13]);
- R3(L, R, MK[14], RK[14]);
- R1(R, L, MK[15], RK[15]);
-
- store_be(out, R, L);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit L = load_be<u32bit>(in, 0);
+ u32bit R = load_be<u32bit>(in, 1);
+
+ R1(L, R, MK[ 0], RK[ 0]);
+ R2(R, L, MK[ 1], RK[ 1]);
+ R3(L, R, MK[ 2], RK[ 2]);
+ R1(R, L, MK[ 3], RK[ 3]);
+ R2(L, R, MK[ 4], RK[ 4]);
+ R3(R, L, MK[ 5], RK[ 5]);
+ R1(L, R, MK[ 6], RK[ 6]);
+ R2(R, L, MK[ 7], RK[ 7]);
+ R3(L, R, MK[ 8], RK[ 8]);
+ R1(R, L, MK[ 9], RK[ 9]);
+ R2(L, R, MK[10], RK[10]);
+ R3(R, L, MK[11], RK[11]);
+ R1(L, R, MK[12], RK[12]);
+ R2(R, L, MK[13], RK[13]);
+ R3(L, R, MK[14], RK[14]);
+ R1(R, L, MK[15], RK[15]);
+
+ store_be(out, R, L);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* CAST-128 Decryption
*/
-void CAST_128::dec(const byte in[], byte out[]) const
+void CAST_128::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0);
- u32bit R = load_be<u32bit>(in, 1);
-
- R1(L, R, MK[15], RK[15]);
- R3(R, L, MK[14], RK[14]);
- R2(L, R, MK[13], RK[13]);
- R1(R, L, MK[12], RK[12]);
- R3(L, R, MK[11], RK[11]);
- R2(R, L, MK[10], RK[10]);
- R1(L, R, MK[ 9], RK[ 9]);
- R3(R, L, MK[ 8], RK[ 8]);
- R2(L, R, MK[ 7], RK[ 7]);
- R1(R, L, MK[ 6], RK[ 6]);
- R3(L, R, MK[ 5], RK[ 5]);
- R2(R, L, MK[ 4], RK[ 4]);
- R1(L, R, MK[ 3], RK[ 3]);
- R3(R, L, MK[ 2], RK[ 2]);
- R2(L, R, MK[ 1], RK[ 1]);
- R1(R, L, MK[ 0], RK[ 0]);
-
- store_be(out, R, L);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit L = load_be<u32bit>(in, 0);
+ u32bit R = load_be<u32bit>(in, 1);
+
+ R1(L, R, MK[15], RK[15]);
+ R3(R, L, MK[14], RK[14]);
+ R2(L, R, MK[13], RK[13]);
+ R1(R, L, MK[12], RK[12]);
+ R3(L, R, MK[11], RK[11]);
+ R2(R, L, MK[10], RK[10]);
+ R1(L, R, MK[ 9], RK[ 9]);
+ R3(R, L, MK[ 8], RK[ 8]);
+ R2(L, R, MK[ 7], RK[ 7]);
+ R1(R, L, MK[ 6], RK[ 6]);
+ R3(L, R, MK[ 5], RK[ 5]);
+ R2(R, L, MK[ 4], RK[ 4]);
+ R1(L, R, MK[ 3], RK[ 3]);
+ R3(R, L, MK[ 2], RK[ 2]);
+ R2(L, R, MK[ 1], RK[ 1]);
+ R1(R, L, MK[ 0], RK[ 0]);
+
+ store_be(out, R, L);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/cast/cast128.h b/src/block/cast/cast128.h
index 680481482..864a4e47e 100644
--- a/src/block/cast/cast128.h
+++ b/src/block/cast/cast128.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL CAST_128 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { MK.clear(); RK.clear(); }
std::string name() const { return "CAST-128"; }
BlockCipher* clone() const { return new CAST_128; }
+
CAST_128() : BlockCipher(8, 11, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static void key_schedule(u32bit[16], u32bit[4]);
diff --git a/src/block/cast/cast256.cpp b/src/block/cast/cast256.cpp
index 22ff876fa..7a4a4e805 100644
--- a/src/block/cast/cast256.cpp
+++ b/src/block/cast/cast256.cpp
@@ -48,77 +48,89 @@ void round3(u32bit& out, u32bit in, u32bit mask, u32bit rot)
/*
* CAST-256 Encryption
*/
-void CAST_256::enc(const byte in[], byte out[]) const
+void CAST_256::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_be<u32bit>(in, 0);
- u32bit B = load_be<u32bit>(in, 1);
- u32bit C = load_be<u32bit>(in, 2);
- u32bit D = load_be<u32bit>(in, 3);
-
- round1(C, D, MK[ 0], RK[ 0]); round2(B, C, MK[ 1], RK[ 1]);
- round3(A, B, MK[ 2], RK[ 2]); round1(D, A, MK[ 3], RK[ 3]);
- round1(C, D, MK[ 4], RK[ 4]); round2(B, C, MK[ 5], RK[ 5]);
- round3(A, B, MK[ 6], RK[ 6]); round1(D, A, MK[ 7], RK[ 7]);
- round1(C, D, MK[ 8], RK[ 8]); round2(B, C, MK[ 9], RK[ 9]);
- round3(A, B, MK[10], RK[10]); round1(D, A, MK[11], RK[11]);
- round1(C, D, MK[12], RK[12]); round2(B, C, MK[13], RK[13]);
- round3(A, B, MK[14], RK[14]); round1(D, A, MK[15], RK[15]);
- round1(C, D, MK[16], RK[16]); round2(B, C, MK[17], RK[17]);
- round3(A, B, MK[18], RK[18]); round1(D, A, MK[19], RK[19]);
- round1(C, D, MK[20], RK[20]); round2(B, C, MK[21], RK[21]);
- round3(A, B, MK[22], RK[22]); round1(D, A, MK[23], RK[23]);
- round1(D, A, MK[27], RK[27]); round3(A, B, MK[26], RK[26]);
- round2(B, C, MK[25], RK[25]); round1(C, D, MK[24], RK[24]);
- round1(D, A, MK[31], RK[31]); round3(A, B, MK[30], RK[30]);
- round2(B, C, MK[29], RK[29]); round1(C, D, MK[28], RK[28]);
- round1(D, A, MK[35], RK[35]); round3(A, B, MK[34], RK[34]);
- round2(B, C, MK[33], RK[33]); round1(C, D, MK[32], RK[32]);
- round1(D, A, MK[39], RK[39]); round3(A, B, MK[38], RK[38]);
- round2(B, C, MK[37], RK[37]); round1(C, D, MK[36], RK[36]);
- round1(D, A, MK[43], RK[43]); round3(A, B, MK[42], RK[42]);
- round2(B, C, MK[41], RK[41]); round1(C, D, MK[40], RK[40]);
- round1(D, A, MK[47], RK[47]); round3(A, B, MK[46], RK[46]);
- round2(B, C, MK[45], RK[45]); round1(C, D, MK[44], RK[44]);
-
- store_be(out, A, B, C, D);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_be<u32bit>(in, 0);
+ u32bit B = load_be<u32bit>(in, 1);
+ u32bit C = load_be<u32bit>(in, 2);
+ u32bit D = load_be<u32bit>(in, 3);
+
+ round1(C, D, MK[ 0], RK[ 0]); round2(B, C, MK[ 1], RK[ 1]);
+ round3(A, B, MK[ 2], RK[ 2]); round1(D, A, MK[ 3], RK[ 3]);
+ round1(C, D, MK[ 4], RK[ 4]); round2(B, C, MK[ 5], RK[ 5]);
+ round3(A, B, MK[ 6], RK[ 6]); round1(D, A, MK[ 7], RK[ 7]);
+ round1(C, D, MK[ 8], RK[ 8]); round2(B, C, MK[ 9], RK[ 9]);
+ round3(A, B, MK[10], RK[10]); round1(D, A, MK[11], RK[11]);
+ round1(C, D, MK[12], RK[12]); round2(B, C, MK[13], RK[13]);
+ round3(A, B, MK[14], RK[14]); round1(D, A, MK[15], RK[15]);
+ round1(C, D, MK[16], RK[16]); round2(B, C, MK[17], RK[17]);
+ round3(A, B, MK[18], RK[18]); round1(D, A, MK[19], RK[19]);
+ round1(C, D, MK[20], RK[20]); round2(B, C, MK[21], RK[21]);
+ round3(A, B, MK[22], RK[22]); round1(D, A, MK[23], RK[23]);
+ round1(D, A, MK[27], RK[27]); round3(A, B, MK[26], RK[26]);
+ round2(B, C, MK[25], RK[25]); round1(C, D, MK[24], RK[24]);
+ round1(D, A, MK[31], RK[31]); round3(A, B, MK[30], RK[30]);
+ round2(B, C, MK[29], RK[29]); round1(C, D, MK[28], RK[28]);
+ round1(D, A, MK[35], RK[35]); round3(A, B, MK[34], RK[34]);
+ round2(B, C, MK[33], RK[33]); round1(C, D, MK[32], RK[32]);
+ round1(D, A, MK[39], RK[39]); round3(A, B, MK[38], RK[38]);
+ round2(B, C, MK[37], RK[37]); round1(C, D, MK[36], RK[36]);
+ round1(D, A, MK[43], RK[43]); round3(A, B, MK[42], RK[42]);
+ round2(B, C, MK[41], RK[41]); round1(C, D, MK[40], RK[40]);
+ round1(D, A, MK[47], RK[47]); round3(A, B, MK[46], RK[46]);
+ round2(B, C, MK[45], RK[45]); round1(C, D, MK[44], RK[44]);
+
+ store_be(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* CAST-256 Decryption
*/
-void CAST_256::dec(const byte in[], byte out[]) const
+void CAST_256::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_be<u32bit>(in, 0);
- u32bit B = load_be<u32bit>(in, 1);
- u32bit C = load_be<u32bit>(in, 2);
- u32bit D = load_be<u32bit>(in, 3);
-
- round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]);
- round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]);
- round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]);
- round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]);
- round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]);
- round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]);
- round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]);
- round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]);
- round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]);
- round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]);
- round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]);
- round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]);
- round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]);
- round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]);
- round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]);
- round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]);
- round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]);
- round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]);
- round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]);
- round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]);
- round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]);
- round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]);
- round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]);
- round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]);
-
- store_be(out, A, B, C, D);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_be<u32bit>(in, 0);
+ u32bit B = load_be<u32bit>(in, 1);
+ u32bit C = load_be<u32bit>(in, 2);
+ u32bit D = load_be<u32bit>(in, 3);
+
+ round1(C, D, MK[44], RK[44]); round2(B, C, MK[45], RK[45]);
+ round3(A, B, MK[46], RK[46]); round1(D, A, MK[47], RK[47]);
+ round1(C, D, MK[40], RK[40]); round2(B, C, MK[41], RK[41]);
+ round3(A, B, MK[42], RK[42]); round1(D, A, MK[43], RK[43]);
+ round1(C, D, MK[36], RK[36]); round2(B, C, MK[37], RK[37]);
+ round3(A, B, MK[38], RK[38]); round1(D, A, MK[39], RK[39]);
+ round1(C, D, MK[32], RK[32]); round2(B, C, MK[33], RK[33]);
+ round3(A, B, MK[34], RK[34]); round1(D, A, MK[35], RK[35]);
+ round1(C, D, MK[28], RK[28]); round2(B, C, MK[29], RK[29]);
+ round3(A, B, MK[30], RK[30]); round1(D, A, MK[31], RK[31]);
+ round1(C, D, MK[24], RK[24]); round2(B, C, MK[25], RK[25]);
+ round3(A, B, MK[26], RK[26]); round1(D, A, MK[27], RK[27]);
+ round1(D, A, MK[23], RK[23]); round3(A, B, MK[22], RK[22]);
+ round2(B, C, MK[21], RK[21]); round1(C, D, MK[20], RK[20]);
+ round1(D, A, MK[19], RK[19]); round3(A, B, MK[18], RK[18]);
+ round2(B, C, MK[17], RK[17]); round1(C, D, MK[16], RK[16]);
+ round1(D, A, MK[15], RK[15]); round3(A, B, MK[14], RK[14]);
+ round2(B, C, MK[13], RK[13]); round1(C, D, MK[12], RK[12]);
+ round1(D, A, MK[11], RK[11]); round3(A, B, MK[10], RK[10]);
+ round2(B, C, MK[ 9], RK[ 9]); round1(C, D, MK[ 8], RK[ 8]);
+ round1(D, A, MK[ 7], RK[ 7]); round3(A, B, MK[ 6], RK[ 6]);
+ round2(B, C, MK[ 5], RK[ 5]); round1(C, D, MK[ 4], RK[ 4]);
+ round1(D, A, MK[ 3], RK[ 3]); round3(A, B, MK[ 2], RK[ 2]);
+ round2(B, C, MK[ 1], RK[ 1]); round1(C, D, MK[ 0], RK[ 0]);
+
+ store_be(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/cast/cast256.h b/src/block/cast/cast256.h
index cd48edd5e..1be7fa9cf 100644
--- a/src/block/cast/cast256.h
+++ b/src/block/cast/cast256.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL CAST_256 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { MK.clear(); RK.clear(); }
std::string name() const { return "CAST-256"; }
BlockCipher* clone() const { return new CAST_256; }
+
CAST_256() : BlockCipher(16, 4, 32, 4) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static const u32bit KEY_MASK[192];
diff --git a/src/block/des/des.cpp b/src/block/des/des.cpp
index 37520e0fc..1c9d37e6b 100644
--- a/src/block/des/des.cpp
+++ b/src/block/des/des.cpp
@@ -139,51 +139,63 @@ void des_decrypt(u32bit& L, u32bit& R,
/*
* DES Encryption
*/
-void DES::enc(const byte in[], byte out[]) const
+void DES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
- (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
- (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
- (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
- u32bit L = static_cast<u32bit>(T >> 32);
- u32bit R = static_cast<u32bit>(T);
+ des_encrypt(L, R, round_key);
- des_encrypt(L, R, round_key);
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
- T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
- (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
- (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
- (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = rotate_left(T, 32);
- T = rotate_left(T, 32);
+ store_be(T, out);
- store_be(T, out);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* DES Decryption
*/
-void DES::dec(const byte in[], byte out[]) const
+void DES::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
- (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
- (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
- (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
- u32bit L = static_cast<u32bit>(T >> 32);
- u32bit R = static_cast<u32bit>(T);
+ des_decrypt(L, R, round_key);
- des_decrypt(L, R, round_key);
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
- T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
- (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
- (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
- (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = rotate_left(T, 32);
- T = rotate_left(T, 32);
+ store_be(T, out);
- store_be(T, out);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
@@ -197,55 +209,67 @@ void DES::key_schedule(const byte key[], u32bit)
/*
* TripleDES Encryption
*/
-void TripleDES::enc(const byte in[], byte out[]) const
+void TripleDES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
- (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
- (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
- (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
- u32bit L = static_cast<u32bit>(T >> 32);
- u32bit R = static_cast<u32bit>(T);
+ des_encrypt(L, R, round_key);
+ des_decrypt(R, L, round_key + 32);
+ des_encrypt(L, R, round_key + 64);
- des_encrypt(L, R, round_key);
- des_decrypt(R, L, round_key + 32);
- des_encrypt(L, R, round_key + 64);
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
- T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
- (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
- (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
- (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = rotate_left(T, 32);
- T = rotate_left(T, 32);
+ store_be(T, out);
- store_be(T, out);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* TripleDES Decryption
*/
-void TripleDES::dec(const byte in[], byte out[]) const
+void TripleDES::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
- (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
- (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
- (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u64bit T = (DES_IPTAB1[in[0]] ) | (DES_IPTAB1[in[1]] << 1) |
+ (DES_IPTAB1[in[2]] << 2) | (DES_IPTAB1[in[3]] << 3) |
+ (DES_IPTAB1[in[4]] << 4) | (DES_IPTAB1[in[5]] << 5) |
+ (DES_IPTAB1[in[6]] << 6) | (DES_IPTAB2[in[7]] );
+
+ u32bit L = static_cast<u32bit>(T >> 32);
+ u32bit R = static_cast<u32bit>(T);
- u32bit L = static_cast<u32bit>(T >> 32);
- u32bit R = static_cast<u32bit>(T);
+ des_decrypt(L, R, round_key + 64);
+ des_encrypt(R, L, round_key + 32);
+ des_decrypt(L, R, round_key);
- des_decrypt(L, R, round_key + 64);
- des_encrypt(R, L, round_key + 32);
- des_decrypt(L, R, round_key);
+ T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
+ (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
+ (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
+ (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
- T = (DES_FPTAB1[get_byte(0, L)] << 5) | (DES_FPTAB1[get_byte(1, L)] << 3) |
- (DES_FPTAB1[get_byte(2, L)] << 1) | (DES_FPTAB2[get_byte(3, L)] << 1) |
- (DES_FPTAB1[get_byte(0, R)] << 4) | (DES_FPTAB1[get_byte(1, R)] << 2) |
- (DES_FPTAB1[get_byte(2, R)] ) | (DES_FPTAB2[get_byte(3, R)] );
+ T = rotate_left(T, 32);
- T = rotate_left(T, 32);
+ store_be(T, out);
- store_be(T, out);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/des/des.h b/src/block/des/des.h
index 6fa59de5e..856aaf60c 100644
--- a/src/block/des/des.h
+++ b/src/block/des/des.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL DES : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { round_key.clear(); }
std::string name() const { return "DES"; }
BlockCipher* clone() const { return new DES; }
+
DES() : BlockCipher(8, 8) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 32> round_key;
@@ -36,13 +38,15 @@ class BOTAN_DLL DES : public BlockCipher
class BOTAN_DLL TripleDES : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { round_key.clear(); }
std::string name() const { return "TripleDES"; }
BlockCipher* clone() const { return new TripleDES; }
+
TripleDES() : BlockCipher(8, 16, 24, 8) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 96> round_key;
diff --git a/src/block/des/desx.cpp b/src/block/des/desx.cpp
index e557901d3..1fc1c47f2 100644
--- a/src/block/des/desx.cpp
+++ b/src/block/des/desx.cpp
@@ -13,21 +13,33 @@ namespace Botan {
/*
* DESX Encryption
*/
-void DESX::enc(const byte in[], byte out[]) const
+void DESX::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- xor_buf(out, in, K1.begin(), BLOCK_SIZE);
- des.encrypt(out);
- xor_buf(out, K2.begin(), BLOCK_SIZE);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ xor_buf(out, in, K1.begin(), BLOCK_SIZE);
+ des.encrypt(out);
+ xor_buf(out, K2.begin(), BLOCK_SIZE);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* DESX Decryption
*/
-void DESX::dec(const byte in[], byte out[]) const
+void DESX::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- xor_buf(out, in, K2.begin(), BLOCK_SIZE);
- des.decrypt(out);
- xor_buf(out, K1.begin(), BLOCK_SIZE);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ xor_buf(out, in, K2.begin(), BLOCK_SIZE);
+ des.decrypt(out);
+ xor_buf(out, K1.begin(), BLOCK_SIZE);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/des/desx.h b/src/block/des/desx.h
index 49ecc2421..d22895296 100644
--- a/src/block/des/desx.h
+++ b/src/block/des/desx.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL DESX : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { des.clear(); K1.clear(); K2.clear(); }
std::string name() const { return "DESX"; }
BlockCipher* clone() const { return new DESX; }
+
DESX() : BlockCipher(8, 24) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<byte, 8> K1, K2;
DES des;
diff --git a/src/block/gost_28147/gost_28147.cpp b/src/block/gost_28147/gost_28147.cpp
index bfd092c56..272f1bcab 100644
--- a/src/block/gost_28147/gost_28147.cpp
+++ b/src/block/gost_28147/gost_28147.cpp
@@ -84,47 +84,58 @@ GOST_28147_89::GOST_28147_89(const GOST_28147_89_Params& param) :
/*
* GOST Encryption
*/
-void GOST_28147_89::enc(const byte in[], byte out[]) const
+void GOST_28147_89::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
-
- for(size_t i = 0; i != 3; ++i)
+ for(u32bit i = 0; i != blocks; ++i)
{
- GOST_2ROUND(N1, N2, 0, 1);
- GOST_2ROUND(N1, N2, 2, 3);
- GOST_2ROUND(N1, N2, 4, 5);
- GOST_2ROUND(N1, N2, 6, 7);
- }
+ u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
- GOST_2ROUND(N1, N2, 7, 6);
- GOST_2ROUND(N1, N2, 5, 4);
- GOST_2ROUND(N1, N2, 3, 2);
- GOST_2ROUND(N1, N2, 1, 0);
+ for(size_t j = 0; j != 3; ++j)
+ {
+ GOST_2ROUND(N1, N2, 0, 1);
+ GOST_2ROUND(N1, N2, 2, 3);
+ GOST_2ROUND(N1, N2, 4, 5);
+ GOST_2ROUND(N1, N2, 6, 7);
+ }
- store_le(out, N2, N1);
+ GOST_2ROUND(N1, N2, 7, 6);
+ GOST_2ROUND(N1, N2, 5, 4);
+ GOST_2ROUND(N1, N2, 3, 2);
+ GOST_2ROUND(N1, N2, 1, 0);
+
+ store_le(out, N2, N1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* GOST Decryption
*/
-void GOST_28147_89::dec(const byte in[], byte out[]) const
+void GOST_28147_89::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit N1 = load_le<u32bit>(in, 0), N2 = load_le<u32bit>(in, 1);
- GOST_2ROUND(N1, N2, 0, 1);
- GOST_2ROUND(N1, N2, 2, 3);
- GOST_2ROUND(N1, N2, 4, 5);
- GOST_2ROUND(N1, N2, 6, 7);
+ GOST_2ROUND(N1, N2, 0, 1);
+ GOST_2ROUND(N1, N2, 2, 3);
+ GOST_2ROUND(N1, N2, 4, 5);
+ GOST_2ROUND(N1, N2, 6, 7);
- for(size_t i = 0; i != 3; ++i)
- {
- GOST_2ROUND(N1, N2, 7, 6);
- GOST_2ROUND(N1, N2, 5, 4);
- GOST_2ROUND(N1, N2, 3, 2);
- GOST_2ROUND(N1, N2, 1, 0);
- }
+ for(size_t i = 0; i != 3; ++i)
+ {
+ GOST_2ROUND(N1, N2, 7, 6);
+ GOST_2ROUND(N1, N2, 5, 4);
+ GOST_2ROUND(N1, N2, 3, 2);
+ GOST_2ROUND(N1, N2, 1, 0);
+ }
- store_le(out, N2, N1);
+ store_le(out, N2, N1);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h
index 96d24c669..18c1d0a29 100644
--- a/src/block/gost_28147/gost_28147.h
+++ b/src/block/gost_28147/gost_28147.h
@@ -44,6 +44,9 @@ class GOST_28147_89_Params
class BOTAN_DLL GOST_28147_89 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const { return "GOST-28147-89"; }
@@ -54,8 +57,6 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher
GOST_28147_89(const SecureBuffer<u32bit, 1024>& other_SBOX) :
BlockCipher(8, 32), SBOX(other_SBOX) {}
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 1024> SBOX;
diff --git a/src/block/idea/idea.cpp b/src/block/idea/idea.cpp
index 5bbe47087..fb5fe83f1 100644
--- a/src/block/idea/idea.cpp
+++ b/src/block/idea/idea.cpp
@@ -60,77 +60,89 @@ u16bit mul_inv(u16bit x)
/*
* IDEA Encryption
*/
-void IDEA::enc(const byte in[], byte out[]) const
+void IDEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit X1 = load_be<u16bit>(in, 0);
- u16bit X2 = load_be<u16bit>(in, 1);
- u16bit X3 = load_be<u16bit>(in, 2);
- u16bit X4 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 8; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- X1 = mul(X1, EK[6*j+0]);
- X2 += EK[6*j+1];
- X3 += EK[6*j+2];
- X4 = mul(X4, EK[6*j+3]);
-
- u16bit T0 = X3;
- X3 = mul(X3 ^ X1, EK[6*j+4]);
-
- u16bit T1 = X2;
- X2 = mul((X2 ^ X4) + X3, EK[6*j+5]);
- X3 += X2;
-
- X1 ^= X2;
- X4 ^= X3;
- X2 ^= T0;
- X3 ^= T1;
+ u16bit X1 = load_be<u16bit>(in, 0);
+ u16bit X2 = load_be<u16bit>(in, 1);
+ u16bit X3 = load_be<u16bit>(in, 2);
+ u16bit X4 = load_be<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 8; ++j)
+ {
+ X1 = mul(X1, EK[6*j+0]);
+ X2 += EK[6*j+1];
+ X3 += EK[6*j+2];
+ X4 = mul(X4, EK[6*j+3]);
+
+ u16bit T0 = X3;
+ X3 = mul(X3 ^ X1, EK[6*j+4]);
+
+ u16bit T1 = X2;
+ X2 = mul((X2 ^ X4) + X3, EK[6*j+5]);
+ X3 += X2;
+
+ X1 ^= X2;
+ X4 ^= X3;
+ X2 ^= T0;
+ X3 ^= T1;
+ }
+
+ X1 = mul(X1, EK[48]);
+ X2 += EK[50];
+ X3 += EK[49];
+ X4 = mul(X4, EK[51]);
+
+ store_be(out, X1, X3, X2, X4);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
-
- X1 = mul(X1, EK[48]);
- X2 += EK[50];
- X3 += EK[49];
- X4 = mul(X4, EK[51]);
-
- store_be(out, X1, X3, X2, X4);
}
/*
* IDEA Decryption
*/
-void IDEA::dec(const byte in[], byte out[]) const
+void IDEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit X1 = load_be<u16bit>(in, 0);
- u16bit X2 = load_be<u16bit>(in, 1);
- u16bit X3 = load_be<u16bit>(in, 2);
- u16bit X4 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 8; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- X1 = mul(X1, DK[6*j+0]);
- X2 += DK[6*j+1];
- X3 += DK[6*j+2];
- X4 = mul(X4, DK[6*j+3]);
-
- u16bit T0 = X3;
- X3 = mul(X3 ^ X1, DK[6*j+4]);
-
- u16bit T1 = X2;
- X2 = mul((X2 ^ X4) + X3, DK[6*j+5]);
- X3 += X2;
-
- X1 ^= X2;
- X4 ^= X3;
- X2 ^= T0;
- X3 ^= T1;
+ u16bit X1 = load_be<u16bit>(in, 0);
+ u16bit X2 = load_be<u16bit>(in, 1);
+ u16bit X3 = load_be<u16bit>(in, 2);
+ u16bit X4 = load_be<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 8; ++j)
+ {
+ X1 = mul(X1, DK[6*j+0]);
+ X2 += DK[6*j+1];
+ X3 += DK[6*j+2];
+ X4 = mul(X4, DK[6*j+3]);
+
+ u16bit T0 = X3;
+ X3 = mul(X3 ^ X1, DK[6*j+4]);
+
+ u16bit T1 = X2;
+ X2 = mul((X2 ^ X4) + X3, DK[6*j+5]);
+ X3 += X2;
+
+ X1 ^= X2;
+ X4 ^= X3;
+ X2 ^= T0;
+ X3 ^= T1;
+ }
+
+ X1 = mul(X1, DK[48]);
+ X2 += DK[50];
+ X3 += DK[49];
+ X4 = mul(X4, DK[51]);
+
+ store_be(out, X1, X3, X2, X4);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
-
- X1 = mul(X1, DK[48]);
- X2 += DK[50];
- X3 += DK[49];
- X4 = mul(X4, DK[51]);
-
- store_be(out, X1, X3, X2, X4);
}
/*
diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h
index 2c53cd0e4..59484531b 100644
--- a/src/block/idea/idea.h
+++ b/src/block/idea/idea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL IDEA : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); DK.clear(); }
std::string name() const { return "IDEA"; }
BlockCipher* clone() const { return new IDEA; }
+
IDEA() : BlockCipher(8, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 52> EK, DK;
};
diff --git a/src/block/kasumi/kasumi.cpp b/src/block/kasumi/kasumi.cpp
index e051ddefb..dff6db13c 100644
--- a/src/block/kasumi/kasumi.cpp
+++ b/src/block/kasumi/kasumi.cpp
@@ -109,79 +109,91 @@ u16bit FI(u16bit I, u16bit K)
/*
* KASUMI Encryption
*/
-void KASUMI::enc(const byte in[], byte out[]) const
+void KASUMI::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit B0 = load_be<u16bit>(in, 0);
- u16bit B1 = load_be<u16bit>(in, 1);
- u16bit B2 = load_be<u16bit>(in, 2);
- u16bit B3 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 8; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u16bit* K = EK + 8*j;
+ u16bit B0 = load_be<u16bit>(in, 0);
+ u16bit B1 = load_be<u16bit>(in, 1);
+ u16bit B2 = load_be<u16bit>(in, 2);
+ u16bit B3 = load_be<u16bit>(in, 3);
- u16bit R = B1 ^ (rotate_left(B0, 1) & K[0]);
- u16bit L = B0 ^ (rotate_left(R, 1) | K[1]);
+ for(u32bit j = 0; j != 8; j += 2)
+ {
+ const u16bit* K = EK + 8*j;
- L = FI(L ^ K[ 2], K[ 3]) ^ R;
- R = FI(R ^ K[ 4], K[ 5]) ^ L;
- L = FI(L ^ K[ 6], K[ 7]) ^ R;
+ u16bit R = B1 ^ (rotate_left(B0, 1) & K[0]);
+ u16bit L = B0 ^ (rotate_left(R, 1) | K[1]);
- R = B2 ^= R;
- L = B3 ^= L;
+ L = FI(L ^ K[ 2], K[ 3]) ^ R;
+ R = FI(R ^ K[ 4], K[ 5]) ^ L;
+ L = FI(L ^ K[ 6], K[ 7]) ^ R;
- R = FI(R ^ K[10], K[11]) ^ L;
- L = FI(L ^ K[12], K[13]) ^ R;
- R = FI(R ^ K[14], K[15]) ^ L;
+ R = B2 ^= R;
+ L = B3 ^= L;
- R ^= (rotate_left(L, 1) & K[8]);
- L ^= (rotate_left(R, 1) | K[9]);
+ R = FI(R ^ K[10], K[11]) ^ L;
+ L = FI(L ^ K[12], K[13]) ^ R;
+ R = FI(R ^ K[14], K[15]) ^ L;
- B0 ^= L;
- B1 ^= R;
- }
+ R ^= (rotate_left(L, 1) & K[8]);
+ L ^= (rotate_left(R, 1) | K[9]);
+
+ B0 ^= L;
+ B1 ^= R;
+ }
- store_be(out, B0, B1, B2, B3);
+ store_be(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* KASUMI Decryption
*/
-void KASUMI::dec(const byte in[], byte out[]) const
+void KASUMI::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit B0 = load_be<u16bit>(in, 0);
- u16bit B1 = load_be<u16bit>(in, 1);
- u16bit B2 = load_be<u16bit>(in, 2);
- u16bit B3 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 8; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u16bit* K = EK + 8*(6-j);
+ u16bit B0 = load_be<u16bit>(in, 0);
+ u16bit B1 = load_be<u16bit>(in, 1);
+ u16bit B2 = load_be<u16bit>(in, 2);
+ u16bit B3 = load_be<u16bit>(in, 3);
- u16bit L = B2, R = B3;
+ for(u32bit j = 0; j != 8; j += 2)
+ {
+ const u16bit* K = EK + 8*(6-j);
- L = FI(L ^ K[10], K[11]) ^ R;
- R = FI(R ^ K[12], K[13]) ^ L;
- L = FI(L ^ K[14], K[15]) ^ R;
+ u16bit L = B2, R = B3;
- L ^= (rotate_left(R, 1) & K[8]);
- R ^= (rotate_left(L, 1) | K[9]);
+ L = FI(L ^ K[10], K[11]) ^ R;
+ R = FI(R ^ K[12], K[13]) ^ L;
+ L = FI(L ^ K[14], K[15]) ^ R;
- R = B0 ^= R;
- L = B1 ^= L;
+ L ^= (rotate_left(R, 1) & K[8]);
+ R ^= (rotate_left(L, 1) | K[9]);
- L ^= (rotate_left(R, 1) & K[0]);
- R ^= (rotate_left(L, 1) | K[1]);
+ R = B0 ^= R;
+ L = B1 ^= L;
- R = FI(R ^ K[2], K[3]) ^ L;
- L = FI(L ^ K[4], K[5]) ^ R;
- R = FI(R ^ K[6], K[7]) ^ L;
+ L ^= (rotate_left(R, 1) & K[0]);
+ R ^= (rotate_left(L, 1) | K[1]);
- B2 ^= L;
- B3 ^= R;
- }
+ R = FI(R ^ K[2], K[3]) ^ L;
+ L = FI(L ^ K[4], K[5]) ^ R;
+ R = FI(R ^ K[6], K[7]) ^ L;
+
+ B2 ^= L;
+ B3 ^= R;
+ }
- store_be(out, B0, B1, B2, B3);
+ store_be(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/kasumi/kasumi.h b/src/block/kasumi/kasumi.h
index df49fa9eb..0f5a5d182 100644
--- a/src/block/kasumi/kasumi.h
+++ b/src/block/kasumi/kasumi.h
@@ -18,14 +18,15 @@ namespace Botan {
class BOTAN_DLL KASUMI : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const { return "KASUMI"; }
BlockCipher* clone() const { return new KASUMI; }
KASUMI() : BlockCipher(8, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 64> EK;
diff --git a/src/block/lion/lion.cpp b/src/block/lion/lion.cpp
index c7cdf6d13..83c1e3aa3 100644
--- a/src/block/lion/lion.cpp
+++ b/src/block/lion/lion.cpp
@@ -14,41 +14,53 @@ namespace Botan {
/*
* Lion Encryption
*/
-void Lion::enc(const byte in[], byte out[]) const
+void Lion::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
SecureVector<byte> buffer(LEFT_SIZE);
- xor_buf(buffer, in, key1, LEFT_SIZE);
- cipher->set_key(buffer, LEFT_SIZE);
- cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ xor_buf(buffer, in, key1, LEFT_SIZE);
+ cipher->set_key(buffer, LEFT_SIZE);
+ cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
- hash->update(out + LEFT_SIZE, RIGHT_SIZE);
- hash->final(buffer);
- xor_buf(out, in, buffer, LEFT_SIZE);
+ hash->update(out + LEFT_SIZE, RIGHT_SIZE);
+ hash->final(buffer);
+ xor_buf(out, in, buffer, LEFT_SIZE);
- xor_buf(buffer, out, key2, LEFT_SIZE);
- cipher->set_key(buffer, LEFT_SIZE);
- cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE);
+ xor_buf(buffer, out, key2, LEFT_SIZE);
+ cipher->set_key(buffer, LEFT_SIZE);
+ cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Lion Decryption
*/
-void Lion::dec(const byte in[], byte out[]) const
+void Lion::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
SecureVector<byte> buffer(LEFT_SIZE);
- xor_buf(buffer, in, key2, LEFT_SIZE);
- cipher->set_key(buffer, LEFT_SIZE);
- cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ xor_buf(buffer, in, key2, LEFT_SIZE);
+ cipher->set_key(buffer, LEFT_SIZE);
+ cipher->encrypt(in + LEFT_SIZE, out + LEFT_SIZE, RIGHT_SIZE);
+
+ hash->update(out + LEFT_SIZE, RIGHT_SIZE);
+ hash->final(buffer);
+ xor_buf(out, in, buffer, LEFT_SIZE);
- hash->update(out + LEFT_SIZE, RIGHT_SIZE);
- hash->final(buffer);
- xor_buf(out, in, buffer, LEFT_SIZE);
+ xor_buf(buffer, out, key1, LEFT_SIZE);
+ cipher->set_key(buffer, LEFT_SIZE);
+ cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE);
- xor_buf(buffer, out, key1, LEFT_SIZE);
- cipher->set_key(buffer, LEFT_SIZE);
- cipher->encrypt(out + LEFT_SIZE, RIGHT_SIZE);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/lion/lion.h b/src/block/lion/lion.h
index 5bc4e72c0..d421771d6 100644
--- a/src/block/lion/lion.h
+++ b/src/block/lion/lion.h
@@ -20,6 +20,9 @@ namespace Botan {
class BOTAN_DLL Lion : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const;
BlockCipher* clone() const;
@@ -27,8 +30,6 @@ class BOTAN_DLL Lion : public BlockCipher
Lion(HashFunction*, StreamCipher*, u32bit);
~Lion() { delete hash; delete cipher; }
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
const u32bit LEFT_SIZE, RIGHT_SIZE;
diff --git a/src/block/lubyrack/lubyrack.cpp b/src/block/lubyrack/lubyrack.cpp
index a9d2b1db2..6ad64f2b0 100644
--- a/src/block/lubyrack/lubyrack.cpp
+++ b/src/block/lubyrack/lubyrack.cpp
@@ -13,59 +13,71 @@ namespace Botan {
/*
* Luby-Rackoff Encryption
*/
-void LubyRackoff::enc(const byte in[], byte out[]) const
+void LubyRackoff::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- const u32bit len = hash->OUTPUT_LENGTH;
-
- SecureVector<byte> buffer(len);
- hash->update(K1);
- hash->update(in, len);
- hash->final(buffer);
- xor_buf(out + len, in + len, buffer, len);
-
- hash->update(K2);
- hash->update(out + len, len);
- hash->final(buffer);
- xor_buf(out, in, buffer, len);
-
- hash->update(K1);
- hash->update(out, len);
- hash->final(buffer);
- xor_buf(out + len, buffer, len);
-
- hash->update(K2);
- hash->update(out + len, len);
- hash->final(buffer);
- xor_buf(out, buffer, len);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ const u32bit len = hash->OUTPUT_LENGTH;
+
+ SecureVector<byte> buffer(len);
+ hash->update(K1);
+ hash->update(in, len);
+ hash->final(buffer);
+ xor_buf(out + len, in + len, buffer, len);
+
+ hash->update(K2);
+ hash->update(out + len, len);
+ hash->final(buffer);
+ xor_buf(out, in, buffer, len);
+
+ hash->update(K1);
+ hash->update(out, len);
+ hash->final(buffer);
+ xor_buf(out + len, buffer, len);
+
+ hash->update(K2);
+ hash->update(out + len, len);
+ hash->final(buffer);
+ xor_buf(out, buffer, len);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Luby-Rackoff Decryption
*/
-void LubyRackoff::dec(const byte in[], byte out[]) const
+void LubyRackoff::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- const u32bit len = hash->OUTPUT_LENGTH;
-
- SecureVector<byte> buffer(len);
- hash->update(K2);
- hash->update(in + len, len);
- hash->final(buffer);
- xor_buf(out, in, buffer, len);
-
- hash->update(K1);
- hash->update(out, len);
- hash->final(buffer);
- xor_buf(out + len, in + len, buffer, len);
-
- hash->update(K2);
- hash->update(out + len, len);
- hash->final(buffer);
- xor_buf(out, buffer, len);
-
- hash->update(K1);
- hash->update(out, len);
- hash->final(buffer);
- xor_buf(out + len, buffer, len);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ const u32bit len = hash->OUTPUT_LENGTH;
+
+ SecureVector<byte> buffer(len);
+ hash->update(K2);
+ hash->update(in + len, len);
+ hash->final(buffer);
+ xor_buf(out, in, buffer, len);
+
+ hash->update(K1);
+ hash->update(out, len);
+ hash->final(buffer);
+ xor_buf(out + len, in + len, buffer, len);
+
+ hash->update(K2);
+ hash->update(out + len, len);
+ hash->final(buffer);
+ xor_buf(out, buffer, len);
+
+ hash->update(K1);
+ hash->update(out, len);
+ hash->final(buffer);
+ xor_buf(out + len, buffer, len);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/lubyrack/lubyrack.h b/src/block/lubyrack/lubyrack.h
index ebde31304..940b34603 100644
--- a/src/block/lubyrack/lubyrack.h
+++ b/src/block/lubyrack/lubyrack.h
@@ -19,6 +19,9 @@ namespace Botan {
class BOTAN_DLL LubyRackoff : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const;
BlockCipher* clone() const;
@@ -26,9 +29,8 @@ class BOTAN_DLL LubyRackoff : public BlockCipher
LubyRackoff(HashFunction* hash);
~LubyRackoff() { delete hash; }
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
+
HashFunction* hash;
SecureVector<byte> K1, K2;
};
diff --git a/src/block/mars/mars.cpp b/src/block/mars/mars.cpp
index 08c8409c5..69556acb3 100644
--- a/src/block/mars/mars.cpp
+++ b/src/block/mars/mars.cpp
@@ -1,6 +1,6 @@
/*
* MARS
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -50,75 +50,87 @@ u32bit gen_mask(u32bit input)
/*
* MARS Encryption
*/
-void MARS::enc(const byte in[], byte out[]) const
+void MARS::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0) + EK[0];
- u32bit B = load_le<u32bit>(in, 1) + EK[1];
- u32bit C = load_le<u32bit>(in, 2) + EK[2];
- u32bit D = load_le<u32bit>(in, 3) + EK[3];
-
- forward_mix(A, B, C, D);
-
- encrypt_round(A, B, C, D, 0);
- encrypt_round(B, C, D, A, 1);
- encrypt_round(C, D, A, B, 2);
- encrypt_round(D, A, B, C, 3);
- encrypt_round(A, B, C, D, 4);
- encrypt_round(B, C, D, A, 5);
- encrypt_round(C, D, A, B, 6);
- encrypt_round(D, A, B, C, 7);
-
- encrypt_round(A, D, C, B, 8);
- encrypt_round(B, A, D, C, 9);
- encrypt_round(C, B, A, D, 10);
- encrypt_round(D, C, B, A, 11);
- encrypt_round(A, D, C, B, 12);
- encrypt_round(B, A, D, C, 13);
- encrypt_round(C, B, A, D, 14);
- encrypt_round(D, C, B, A, 15);
-
- reverse_mix(A, B, C, D);
-
- A -= EK[36]; B -= EK[37]; C -= EK[38]; D -= EK[39];
-
- store_le(out, A, B, C, D);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_le<u32bit>(in, 0) + EK[0];
+ u32bit B = load_le<u32bit>(in, 1) + EK[1];
+ u32bit C = load_le<u32bit>(in, 2) + EK[2];
+ u32bit D = load_le<u32bit>(in, 3) + EK[3];
+
+ forward_mix(A, B, C, D);
+
+ encrypt_round(A, B, C, D, 0);
+ encrypt_round(B, C, D, A, 1);
+ encrypt_round(C, D, A, B, 2);
+ encrypt_round(D, A, B, C, 3);
+ encrypt_round(A, B, C, D, 4);
+ encrypt_round(B, C, D, A, 5);
+ encrypt_round(C, D, A, B, 6);
+ encrypt_round(D, A, B, C, 7);
+
+ encrypt_round(A, D, C, B, 8);
+ encrypt_round(B, A, D, C, 9);
+ encrypt_round(C, B, A, D, 10);
+ encrypt_round(D, C, B, A, 11);
+ encrypt_round(A, D, C, B, 12);
+ encrypt_round(B, A, D, C, 13);
+ encrypt_round(C, B, A, D, 14);
+ encrypt_round(D, C, B, A, 15);
+
+ reverse_mix(A, B, C, D);
+
+ A -= EK[36]; B -= EK[37]; C -= EK[38]; D -= EK[39];
+
+ store_le(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* MARS Decryption
*/
-void MARS::dec(const byte in[], byte out[]) const
+void MARS::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 3) + EK[39];
- u32bit B = load_le<u32bit>(in, 2) + EK[38];
- u32bit C = load_le<u32bit>(in, 1) + EK[37];
- u32bit D = load_le<u32bit>(in, 0) + EK[36];
-
- forward_mix(A, B, C, D);
-
- decrypt_round(A, B, C, D, 15);
- decrypt_round(B, C, D, A, 14);
- decrypt_round(C, D, A, B, 13);
- decrypt_round(D, A, B, C, 12);
- decrypt_round(A, B, C, D, 11);
- decrypt_round(B, C, D, A, 10);
- decrypt_round(C, D, A, B, 9);
- decrypt_round(D, A, B, C, 8);
-
- decrypt_round(A, D, C, B, 7);
- decrypt_round(B, A, D, C, 6);
- decrypt_round(C, B, A, D, 5);
- decrypt_round(D, C, B, A, 4);
- decrypt_round(A, D, C, B, 3);
- decrypt_round(B, A, D, C, 2);
- decrypt_round(C, B, A, D, 1);
- decrypt_round(D, C, B, A, 0);
-
- reverse_mix(A, B, C, D);
-
- A -= EK[3]; B -= EK[2]; C -= EK[1]; D -= EK[0];
-
- store_le(out, D, C, B, A);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_le<u32bit>(in, 3) + EK[39];
+ u32bit B = load_le<u32bit>(in, 2) + EK[38];
+ u32bit C = load_le<u32bit>(in, 1) + EK[37];
+ u32bit D = load_le<u32bit>(in, 0) + EK[36];
+
+ forward_mix(A, B, C, D);
+
+ decrypt_round(A, B, C, D, 15);
+ decrypt_round(B, C, D, A, 14);
+ decrypt_round(C, D, A, B, 13);
+ decrypt_round(D, A, B, C, 12);
+ decrypt_round(A, B, C, D, 11);
+ decrypt_round(B, C, D, A, 10);
+ decrypt_round(C, D, A, B, 9);
+ decrypt_round(D, A, B, C, 8);
+
+ decrypt_round(A, D, C, B, 7);
+ decrypt_round(B, A, D, C, 6);
+ decrypt_round(C, B, A, D, 5);
+ decrypt_round(D, C, B, A, 4);
+ decrypt_round(A, D, C, B, 3);
+ decrypt_round(B, A, D, C, 2);
+ decrypt_round(C, B, A, D, 1);
+ decrypt_round(D, C, B, A, 0);
+
+ reverse_mix(A, B, C, D);
+
+ A -= EK[3]; B -= EK[2]; C -= EK[1]; D -= EK[0];
+
+ store_le(out, D, C, B, A);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/mars/mars.h b/src/block/mars/mars.h
index ca49695af..7d0bfe4fa 100644
--- a/src/block/mars/mars.h
+++ b/src/block/mars/mars.h
@@ -15,13 +15,15 @@ namespace Botan {
class BOTAN_DLL MARS : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const { return "MARS"; }
BlockCipher* clone() const { return new MARS; }
+
MARS() : BlockCipher(16, 16, 32, 4) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
void encrypt_round(u32bit&, u32bit&, u32bit&, u32bit&, u32bit) const;
diff --git a/src/block/misty1/misty1.cpp b/src/block/misty1/misty1.cpp
index a35ff584d..8a92824cc 100644
--- a/src/block/misty1/misty1.cpp
+++ b/src/block/misty1/misty1.cpp
@@ -1,6 +1,6 @@
/*
* MISTY1
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -102,89 +102,101 @@ u16bit FI(u16bit input, u16bit key7, u16bit key9)
/*
* MISTY1 Encryption
*/
-void MISTY1::enc(const byte in[], byte out[]) const
+void MISTY1::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit B0 = load_be<u16bit>(in, 0);
- u16bit B1 = load_be<u16bit>(in, 1);
- u16bit B2 = load_be<u16bit>(in, 2);
- u16bit B3 = load_be<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 12; j += 3)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u16bit* RK = EK + 8 * j;
+ u16bit B0 = load_be<u16bit>(in, 0);
+ u16bit B1 = load_be<u16bit>(in, 1);
+ u16bit B2 = load_be<u16bit>(in, 2);
+ u16bit B3 = load_be<u16bit>(in, 3);
- B1 ^= B0 & RK[0];
- B0 ^= B1 | RK[1];
- B3 ^= B2 & RK[2];
- B2 ^= B3 | RK[3];
+ for(u32bit j = 0; j != 12; j += 3)
+ {
+ const u16bit* RK = EK + 8 * j;
- u32bit T0, T1;
+ B1 ^= B0 & RK[0];
+ B0 ^= B1 | RK[1];
+ B3 ^= B2 & RK[2];
+ B2 ^= B3 | RK[3];
- T0 = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1;
- T1 = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
- T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
+ u32bit T0, T1;
- B2 ^= T1 ^ RK[13];
- B3 ^= T0;
+ T0 = FI(B0 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B1;
+ T1 = FI(B1 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
+ T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
- T0 = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3;
- T1 = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0;
- T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
+ B2 ^= T1 ^ RK[13];
+ B3 ^= T0;
- B0 ^= T1 ^ RK[23];
- B1 ^= T0;
- }
+ T0 = FI(B2 ^ RK[14], RK[15], RK[16]) ^ B3;
+ T1 = FI(B3 ^ RK[17], RK[18], RK[19]) ^ T0;
+ T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
+
+ B0 ^= T1 ^ RK[23];
+ B1 ^= T0;
+ }
- B1 ^= B0 & EK[96];
- B0 ^= B1 | EK[97];
- B3 ^= B2 & EK[98];
- B2 ^= B3 | EK[99];
+ B1 ^= B0 & EK[96];
+ B0 ^= B1 | EK[97];
+ B3 ^= B2 & EK[98];
+ B2 ^= B3 | EK[99];
- store_be(out, B2, B3, B0, B1);
+ store_be(out, B2, B3, B0, B1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* MISTY1 Decryption
*/
-void MISTY1::dec(const byte in[], byte out[]) const
+void MISTY1::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit B0 = load_be<u16bit>(in, 2);
- u16bit B1 = load_be<u16bit>(in, 3);
- u16bit B2 = load_be<u16bit>(in, 0);
- u16bit B3 = load_be<u16bit>(in, 1);
-
- for(u32bit j = 0; j != 12; j += 3)
+ for(u32bit i = 0; i != blocks; ++i)
{
- const u16bit* RK = DK + 8 * j;
+ u16bit B0 = load_be<u16bit>(in, 2);
+ u16bit B1 = load_be<u16bit>(in, 3);
+ u16bit B2 = load_be<u16bit>(in, 0);
+ u16bit B3 = load_be<u16bit>(in, 1);
- B2 ^= B3 | RK[0];
- B3 ^= B2 & RK[1];
- B0 ^= B1 | RK[2];
- B1 ^= B0 & RK[3];
+ for(u32bit j = 0; j != 12; j += 3)
+ {
+ const u16bit* RK = DK + 8 * j;
- u32bit T0, T1;
+ B2 ^= B3 | RK[0];
+ B3 ^= B2 & RK[1];
+ B0 ^= B1 | RK[2];
+ B1 ^= B0 & RK[3];
- T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3;
- T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
- T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
+ u32bit T0, T1;
- B0 ^= T1 ^ RK[13];
- B1 ^= T0;
+ T0 = FI(B2 ^ RK[ 4], RK[ 5], RK[ 6]) ^ B3;
+ T1 = FI(B3 ^ RK[ 7], RK[ 8], RK[ 9]) ^ T0;
+ T0 = FI(T0 ^ RK[10], RK[11], RK[12]) ^ T1;
- T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1;
- T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0;
- T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
+ B0 ^= T1 ^ RK[13];
+ B1 ^= T0;
- B2 ^= T1 ^ RK[23];
- B3 ^= T0;
- }
+ T0 = FI(B0 ^ RK[14], RK[15], RK[16]) ^ B1;
+ T1 = FI(B1 ^ RK[17], RK[18], RK[19]) ^ T0;
+ T0 = FI(T0 ^ RK[20], RK[21], RK[22]) ^ T1;
+
+ B2 ^= T1 ^ RK[23];
+ B3 ^= T0;
+ }
- B2 ^= B3 | DK[96];
- B3 ^= B2 & DK[97];
- B0 ^= B1 | DK[98];
- B1 ^= B0 & DK[99];
+ B2 ^= B3 | DK[96];
+ B3 ^= B2 & DK[97];
+ B0 ^= B1 | DK[98];
+ B1 ^= B0 & DK[99];
- store_be(out, B0, B1, B2, B3);
+ store_be(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/misty1/misty1.h b/src/block/misty1/misty1.h
index 62d4f856f..8db6881de 100644
--- a/src/block/misty1/misty1.h
+++ b/src/block/misty1/misty1.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL MISTY1 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); DK.clear(); }
std::string name() const { return "MISTY1"; }
BlockCipher* clone() const { return new MISTY1; }
+
MISTY1(u32bit = 8);
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 100> EK, DK;
diff --git a/src/block/noekeon/noekeon.cpp b/src/block/noekeon/noekeon.cpp
index 90eb9ad2b..1b327aa47 100644
--- a/src/block/noekeon/noekeon.cpp
+++ b/src/block/noekeon/noekeon.cpp
@@ -84,65 +84,77 @@ const byte Noekeon::RC[] = {
/*
* Noekeon Encryption
*/
-void Noekeon::enc(const byte in[], byte out[]) const
+void Noekeon::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A0 = load_be<u32bit>(in, 0);
- u32bit A1 = load_be<u32bit>(in, 1);
- u32bit A2 = load_be<u32bit>(in, 2);
- u32bit A3 = load_be<u32bit>(in, 3);
-
- for(u32bit j = 0; j != 16; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- A0 ^= RC[j];
- theta(A0, A1, A2, A3, EK);
+ u32bit A0 = load_be<u32bit>(in, 0);
+ u32bit A1 = load_be<u32bit>(in, 1);
+ u32bit A2 = load_be<u32bit>(in, 2);
+ u32bit A3 = load_be<u32bit>(in, 3);
- A1 = rotate_left(A1, 1);
- A2 = rotate_left(A2, 5);
- A3 = rotate_left(A3, 2);
+ for(u32bit j = 0; j != 16; ++j)
+ {
+ A0 ^= RC[j];
+ theta(A0, A1, A2, A3, EK);
- gamma(A0, A1, A2, A3);
+ A1 = rotate_left(A1, 1);
+ A2 = rotate_left(A2, 5);
+ A3 = rotate_left(A3, 2);
- A1 = rotate_right(A1, 1);
- A2 = rotate_right(A2, 5);
- A3 = rotate_right(A3, 2);
- }
+ gamma(A0, A1, A2, A3);
- A0 ^= RC[16];
- theta(A0, A1, A2, A3, EK);
+ A1 = rotate_right(A1, 1);
+ A2 = rotate_right(A2, 5);
+ A3 = rotate_right(A3, 2);
+ }
+
+ A0 ^= RC[16];
+ theta(A0, A1, A2, A3, EK);
+
+ store_be(out, A0, A1, A2, A3);
- store_be(out, A0, A1, A2, A3);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Noekeon Encryption
*/
-void Noekeon::dec(const byte in[], byte out[]) const
+void Noekeon::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A0 = load_be<u32bit>(in, 0);
- u32bit A1 = load_be<u32bit>(in, 1);
- u32bit A2 = load_be<u32bit>(in, 2);
- u32bit A3 = load_be<u32bit>(in, 3);
-
- for(u32bit j = 16; j != 0; --j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- theta(A0, A1, A2, A3, DK);
- A0 ^= RC[j];
+ u32bit A0 = load_be<u32bit>(in, 0);
+ u32bit A1 = load_be<u32bit>(in, 1);
+ u32bit A2 = load_be<u32bit>(in, 2);
+ u32bit A3 = load_be<u32bit>(in, 3);
- A1 = rotate_left(A1, 1);
- A2 = rotate_left(A2, 5);
- A3 = rotate_left(A3, 2);
+ for(u32bit j = 16; j != 0; --j)
+ {
+ theta(A0, A1, A2, A3, DK);
+ A0 ^= RC[j];
- gamma(A0, A1, A2, A3);
+ A1 = rotate_left(A1, 1);
+ A2 = rotate_left(A2, 5);
+ A3 = rotate_left(A3, 2);
- A1 = rotate_right(A1, 1);
- A2 = rotate_right(A2, 5);
- A3 = rotate_right(A3, 2);
- }
+ gamma(A0, A1, A2, A3);
- theta(A0, A1, A2, A3, DK);
- A0 ^= RC[0];
+ A1 = rotate_right(A1, 1);
+ A2 = rotate_right(A2, 5);
+ A3 = rotate_right(A3, 2);
+ }
- store_be(out, A0, A1, A2, A3);
+ theta(A0, A1, A2, A3, DK);
+ A0 ^= RC[0];
+
+ store_be(out, A0, A1, A2, A3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/noekeon/noekeon.h b/src/block/noekeon/noekeon.h
index 893892446..37b24fb7d 100644
--- a/src/block/noekeon/noekeon.h
+++ b/src/block/noekeon/noekeon.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Noekeon : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Noekeon"; }
BlockCipher* clone() const { return new Noekeon; }
+
Noekeon() : BlockCipher(16, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static const byte RC[17];
diff --git a/src/block/rc2/rc2.cpp b/src/block/rc2/rc2.cpp
index 5827bdb68..b5e4a7d50 100644
--- a/src/block/rc2/rc2.cpp
+++ b/src/block/rc2/rc2.cpp
@@ -14,73 +14,85 @@ namespace Botan {
/*
* RC2 Encryption
*/
-void RC2::enc(const byte in[], byte out[]) const
+void RC2::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit R0 = load_le<u16bit>(in, 0);
- u16bit R1 = load_le<u16bit>(in, 1);
- u16bit R2 = load_le<u16bit>(in, 2);
- u16bit R3 = load_le<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 16; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R0 += (R1 & ~R3) + (R2 & R3) + K[4*j];
- R0 = rotate_left(R0, 1);
+ u16bit R0 = load_le<u16bit>(in, 0);
+ u16bit R1 = load_le<u16bit>(in, 1);
+ u16bit R2 = load_le<u16bit>(in, 2);
+ u16bit R3 = load_le<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 16; ++j)
+ {
+ R0 += (R1 & ~R3) + (R2 & R3) + K[4*j];
+ R0 = rotate_left(R0, 1);
- R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1];
- R1 = rotate_left(R1, 2);
+ R1 += (R2 & ~R0) + (R3 & R0) + K[4*j + 1];
+ R1 = rotate_left(R1, 2);
- R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2];
- R2 = rotate_left(R2, 3);
+ R2 += (R3 & ~R1) + (R0 & R1) + K[4*j + 2];
+ R2 = rotate_left(R2, 3);
- R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3];
- R3 = rotate_left(R3, 5);
+ R3 += (R0 & ~R2) + (R1 & R2) + K[4*j + 3];
+ R3 = rotate_left(R3, 5);
- if(j == 4 || j == 10)
- {
- R0 += K[R3 % 64];
- R1 += K[R0 % 64];
- R2 += K[R1 % 64];
- R3 += K[R2 % 64];
+ if(j == 4 || j == 10)
+ {
+ R0 += K[R3 % 64];
+ R1 += K[R0 % 64];
+ R2 += K[R1 % 64];
+ R3 += K[R2 % 64];
+ }
}
- }
- store_le(out, R0, R1, R2, R3);
+ store_le(out, R0, R1, R2, R3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* RC2 Decryption
*/
-void RC2::dec(const byte in[], byte out[]) const
+void RC2::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit R0 = load_le<u16bit>(in, 0);
- u16bit R1 = load_le<u16bit>(in, 1);
- u16bit R2 = load_le<u16bit>(in, 2);
- u16bit R3 = load_le<u16bit>(in, 3);
-
- for(u32bit j = 0; j != 16; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R3 = rotate_right(R3, 5);
- R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)];
+ u16bit R0 = load_le<u16bit>(in, 0);
+ u16bit R1 = load_le<u16bit>(in, 1);
+ u16bit R2 = load_le<u16bit>(in, 2);
+ u16bit R3 = load_le<u16bit>(in, 3);
+
+ for(u32bit j = 0; j != 16; ++j)
+ {
+ R3 = rotate_right(R3, 5);
+ R3 -= (R0 & ~R2) + (R1 & R2) + K[63 - (4*j + 0)];
- R2 = rotate_right(R2, 3);
- R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)];
+ R2 = rotate_right(R2, 3);
+ R2 -= (R3 & ~R1) + (R0 & R1) + K[63 - (4*j + 1)];
- R1 = rotate_right(R1, 2);
- R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)];
+ R1 = rotate_right(R1, 2);
+ R1 -= (R2 & ~R0) + (R3 & R0) + K[63 - (4*j + 2)];
- R0 = rotate_right(R0, 1);
- R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)];
+ R0 = rotate_right(R0, 1);
+ R0 -= (R1 & ~R3) + (R2 & R3) + K[63 - (4*j + 3)];
- if(j == 4 || j == 10)
- {
- R3 -= K[R2 % 64];
- R2 -= K[R1 % 64];
- R1 -= K[R0 % 64];
- R0 -= K[R3 % 64];
+ if(j == 4 || j == 10)
+ {
+ R3 -= K[R2 % 64];
+ R2 -= K[R1 % 64];
+ R1 -= K[R0 % 64];
+ R0 -= K[R3 % 64];
+ }
}
- }
- store_le(out, R0, R1, R2, R3);
+ store_le(out, R0, R1, R2, R3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/rc2/rc2.h b/src/block/rc2/rc2.h
index cb6f58f04..db623b385 100644
--- a/src/block/rc2/rc2.h
+++ b/src/block/rc2/rc2.h
@@ -18,15 +18,17 @@ namespace Botan {
class BOTAN_DLL RC2 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
static byte EKB_code(u32bit);
void clear() throw() { K.clear(); }
std::string name() const { return "RC2"; }
BlockCipher* clone() const { return new RC2; }
+
RC2() : BlockCipher(8, 1, 32) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 64> K;
diff --git a/src/block/rc5/rc5.cpp b/src/block/rc5/rc5.cpp
index 5d83d5a4e..4bfa27ea0 100644
--- a/src/block/rc5/rc5.cpp
+++ b/src/block/rc5/rc5.cpp
@@ -16,47 +16,59 @@ namespace Botan {
/*
* RC5 Encryption
*/
-void RC5::enc(const byte in[], byte out[]) const
+void RC5::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1);
-
- A += S[0]; B += S[1];
- for(u32bit j = 0; j != ROUNDS; j += 4)
+ for(u32bit i = 0; i != blocks; ++i)
{
- A = rotate_left(A ^ B, B % 32) + S[2*j+2];
- B = rotate_left(B ^ A, A % 32) + S[2*j+3];
- A = rotate_left(A ^ B, B % 32) + S[2*j+4];
- B = rotate_left(B ^ A, A % 32) + S[2*j+5];
- A = rotate_left(A ^ B, B % 32) + S[2*j+6];
- B = rotate_left(B ^ A, A % 32) + S[2*j+7];
- A = rotate_left(A ^ B, B % 32) + S[2*j+8];
- B = rotate_left(B ^ A, A % 32) + S[2*j+9];
- }
+ u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1);
+
+ A += S[0]; B += S[1];
+ for(u32bit j = 0; j != ROUNDS; j += 4)
+ {
+ A = rotate_left(A ^ B, B % 32) + S[2*j+2];
+ B = rotate_left(B ^ A, A % 32) + S[2*j+3];
+ A = rotate_left(A ^ B, B % 32) + S[2*j+4];
+ B = rotate_left(B ^ A, A % 32) + S[2*j+5];
+ A = rotate_left(A ^ B, B % 32) + S[2*j+6];
+ B = rotate_left(B ^ A, A % 32) + S[2*j+7];
+ A = rotate_left(A ^ B, B % 32) + S[2*j+8];
+ B = rotate_left(B ^ A, A % 32) + S[2*j+9];
+ }
- store_le(out, A, B);
+ store_le(out, A, B);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* RC5 Decryption
*/
-void RC5::dec(const byte in[], byte out[]) const
+void RC5::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1);
-
- for(u32bit j = ROUNDS; j != 0; j -= 4)
+ for(u32bit i = 0; i != blocks; ++i)
{
- B = rotate_right(B - S[2*j+1], A % 32) ^ A;
- A = rotate_right(A - S[2*j ], B % 32) ^ B;
- B = rotate_right(B - S[2*j-1], A % 32) ^ A;
- A = rotate_right(A - S[2*j-2], B % 32) ^ B;
- B = rotate_right(B - S[2*j-3], A % 32) ^ A;
- A = rotate_right(A - S[2*j-4], B % 32) ^ B;
- B = rotate_right(B - S[2*j-5], A % 32) ^ A;
- A = rotate_right(A - S[2*j-6], B % 32) ^ B;
- }
- B -= S[1]; A -= S[0];
+ u32bit A = load_le<u32bit>(in, 0), B = load_le<u32bit>(in, 1);
+
+ for(u32bit j = ROUNDS; j != 0; j -= 4)
+ {
+ B = rotate_right(B - S[2*j+1], A % 32) ^ A;
+ A = rotate_right(A - S[2*j ], B % 32) ^ B;
+ B = rotate_right(B - S[2*j-1], A % 32) ^ A;
+ A = rotate_right(A - S[2*j-2], B % 32) ^ B;
+ B = rotate_right(B - S[2*j-3], A % 32) ^ A;
+ A = rotate_right(A - S[2*j-4], B % 32) ^ B;
+ B = rotate_right(B - S[2*j-5], A % 32) ^ A;
+ A = rotate_right(A - S[2*j-6], B % 32) ^ B;
+ }
+ B -= S[1]; A -= S[0];
- store_le(out, A, B);
+ store_le(out, A, B);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/rc5/rc5.h b/src/block/rc5/rc5.h
index 083224720..ff9204710 100644
--- a/src/block/rc5/rc5.h
+++ b/src/block/rc5/rc5.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL RC5 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { S.clear(); }
std::string name() const;
BlockCipher* clone() const { return new RC5(ROUNDS); }
+
RC5(u32bit);
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureVector<u32bit> S;
const u32bit ROUNDS;
diff --git a/src/block/rc6/rc6.cpp b/src/block/rc6/rc6.cpp
index 3b30ea93a..8bda62259 100644
--- a/src/block/rc6/rc6.cpp
+++ b/src/block/rc6/rc6.cpp
@@ -15,85 +15,97 @@ namespace Botan {
/*
* RC6 Encryption
*/
-void RC6::enc(const byte in[], byte out[]) const
+void RC6::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0);
- u32bit B = load_le<u32bit>(in, 1);
- u32bit C = load_le<u32bit>(in, 2);
- u32bit D = load_le<u32bit>(in, 3);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_le<u32bit>(in, 0);
+ u32bit B = load_le<u32bit>(in, 1);
+ u32bit C = load_le<u32bit>(in, 2);
+ u32bit D = load_le<u32bit>(in, 3);
- B += S[0]; D += S[1];
+ B += S[0]; D += S[1];
- for(u32bit j = 0; j != 20; j += 4)
- {
- u32bit T1, T2;
-
- T1 = rotate_left(B*(2*B+1), 5);
- T2 = rotate_left(D*(2*D+1), 5);
- A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2];
- C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3];
-
- T1 = rotate_left(C*(2*C+1), 5);
- T2 = rotate_left(A*(2*A+1), 5);
- B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4];
- D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5];
-
- T1 = rotate_left(D*(2*D+1), 5);
- T2 = rotate_left(B*(2*B+1), 5);
- C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6];
- A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7];
-
- T1 = rotate_left(A*(2*A+1), 5);
- T2 = rotate_left(C*(2*C+1), 5);
- D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8];
- B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9];
- }
+ for(u32bit j = 0; j != 20; j += 4)
+ {
+ u32bit T1, T2;
+
+ T1 = rotate_left(B*(2*B+1), 5);
+ T2 = rotate_left(D*(2*D+1), 5);
+ A = rotate_left(A ^ T1, T2 % 32) + S[2*j+2];
+ C = rotate_left(C ^ T2, T1 % 32) + S[2*j+3];
+
+ T1 = rotate_left(C*(2*C+1), 5);
+ T2 = rotate_left(A*(2*A+1), 5);
+ B = rotate_left(B ^ T1, T2 % 32) + S[2*j+4];
+ D = rotate_left(D ^ T2, T1 % 32) + S[2*j+5];
- A += S[42]; C += S[43];
+ T1 = rotate_left(D*(2*D+1), 5);
+ T2 = rotate_left(B*(2*B+1), 5);
+ C = rotate_left(C ^ T1, T2 % 32) + S[2*j+6];
+ A = rotate_left(A ^ T2, T1 % 32) + S[2*j+7];
- store_le(out, A, B, C, D);
+ T1 = rotate_left(A*(2*A+1), 5);
+ T2 = rotate_left(C*(2*C+1), 5);
+ D = rotate_left(D ^ T1, T2 % 32) + S[2*j+8];
+ B = rotate_left(B ^ T2, T1 % 32) + S[2*j+9];
+ }
+
+ A += S[42]; C += S[43];
+
+ store_le(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* RC6 Decryption
*/
-void RC6::dec(const byte in[], byte out[]) const
+void RC6::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0);
- u32bit B = load_le<u32bit>(in, 1);
- u32bit C = load_le<u32bit>(in, 2);
- u32bit D = load_le<u32bit>(in, 3);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit A = load_le<u32bit>(in, 0);
+ u32bit B = load_le<u32bit>(in, 1);
+ u32bit C = load_le<u32bit>(in, 2);
+ u32bit D = load_le<u32bit>(in, 3);
- C -= S[43]; A -= S[42];
+ C -= S[43]; A -= S[42];
- for(u32bit j = 0; j != 20; j += 4)
- {
- u32bit T1, T2;
-
- T1 = rotate_left(A*(2*A+1), 5);
- T2 = rotate_left(C*(2*C+1), 5);
- B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2;
- D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1;
-
- T1 = rotate_left(D*(2*D+1), 5);
- T2 = rotate_left(B*(2*B+1), 5);
- A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2;
- C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1;
-
- T1 = rotate_left(C*(2*C+1), 5);
- T2 = rotate_left(A*(2*A+1), 5);
- D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2;
- B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1;
-
- T1 = rotate_left(B*(2*B+1), 5);
- T2 = rotate_left(D*(2*D+1), 5);
- C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2;
- A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1;
- }
+ for(u32bit j = 0; j != 20; j += 4)
+ {
+ u32bit T1, T2;
+
+ T1 = rotate_left(A*(2*A+1), 5);
+ T2 = rotate_left(C*(2*C+1), 5);
+ B = rotate_right(B - S[41 - 2*j], T1 % 32) ^ T2;
+ D = rotate_right(D - S[40 - 2*j], T2 % 32) ^ T1;
+
+ T1 = rotate_left(D*(2*D+1), 5);
+ T2 = rotate_left(B*(2*B+1), 5);
+ A = rotate_right(A - S[39 - 2*j], T1 % 32) ^ T2;
+ C = rotate_right(C - S[38 - 2*j], T2 % 32) ^ T1;
- D -= S[1]; B -= S[0];
+ T1 = rotate_left(C*(2*C+1), 5);
+ T2 = rotate_left(A*(2*A+1), 5);
+ D = rotate_right(D - S[37 - 2*j], T1 % 32) ^ T2;
+ B = rotate_right(B - S[36 - 2*j], T2 % 32) ^ T1;
- store_le(out, A, B, C, D);
+ T1 = rotate_left(B*(2*B+1), 5);
+ T2 = rotate_left(D*(2*D+1), 5);
+ C = rotate_right(C - S[35 - 2*j], T1 % 32) ^ T2;
+ A = rotate_right(A - S[34 - 2*j], T2 % 32) ^ T1;
+ }
+
+ D -= S[1]; B -= S[0];
+
+ store_le(out, A, B, C, D);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/rc6/rc6.h b/src/block/rc6/rc6.h
index cb2800be7..5171006f5 100644
--- a/src/block/rc6/rc6.h
+++ b/src/block/rc6/rc6.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL RC6 : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { S.clear(); }
std::string name() const { return "RC6"; }
BlockCipher* clone() const { return new RC6; }
+
RC6() : BlockCipher(16, 1, 32) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 44> S;
diff --git a/src/block/safer/safer_sk.cpp b/src/block/safer/safer_sk.cpp
index f72c4773b..eb5c22fc9 100644
--- a/src/block/safer/safer_sk.cpp
+++ b/src/block/safer/safer_sk.cpp
@@ -1,6 +1,6 @@
/*
* SAFER-SK
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -15,54 +15,75 @@ namespace Botan {
/*
* SAFER-SK Encryption
*/
-void SAFER_SK::enc(const byte in[], byte out[]) const
+void SAFER_SK::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- byte A = in[0], B = in[1], C = in[2], D = in[3],
- E = in[4], F = in[5], G = in[6], H = in[7], X, Y;
- for(u32bit j = 0; j != 16*ROUNDS; j += 16)
+ for(u32bit i = 0; i != blocks; ++i)
{
- A = EXP[A ^ EK[j ]]; B = LOG[B + EK[j+1]];
- C = LOG[C + EK[j+2]]; D = EXP[D ^ EK[j+3]];
- E = EXP[E ^ EK[j+4]]; F = LOG[F + EK[j+5]];
- G = LOG[G + EK[j+6]]; H = EXP[H ^ EK[j+7]];
- A += EK[j+ 8]; B ^= EK[j+ 9]; C ^= EK[j+10]; D += EK[j+11];
- E += EK[j+12]; F ^= EK[j+13]; G ^= EK[j+14]; H += EK[j+15];
- B += A; D += C; F += E; H += G; A += B; C += D; E += F; G += H;
- C += A; G += E; D += B; H += F; A += C; E += G; B += D; F += H;
- H += D; Y = D + H; D = B + F; X = B + D; B = A + E;
- A += B; F = C + G; E = C + F; C = X; G = Y;
+ byte A = in[0], B = in[1], C = in[2], D = in[3],
+ E = in[4], F = in[5], G = in[6], H = in[7], X, Y;
+
+ for(u32bit j = 0; j != 16*ROUNDS; j += 16)
+ {
+ A = EXP[A ^ EK[j ]]; B = LOG[B + EK[j+1]];
+ C = LOG[C + EK[j+2]]; D = EXP[D ^ EK[j+3]];
+ E = EXP[E ^ EK[j+4]]; F = LOG[F + EK[j+5]];
+ G = LOG[G + EK[j+6]]; H = EXP[H ^ EK[j+7]];
+
+ A += EK[j+ 8]; B ^= EK[j+ 9]; C ^= EK[j+10]; D += EK[j+11];
+ E += EK[j+12]; F ^= EK[j+13]; G ^= EK[j+14]; H += EK[j+15];
+
+ B += A; D += C; F += E; H += G; A += B; C += D; E += F; G += H;
+ C += A; G += E; D += B; H += F; A += C; E += G; B += D; F += H;
+ H += D; Y = D + H; D = B + F; X = B + D; B = A + E;
+ A += B; F = C + G; E = C + F; C = X; G = Y;
+ }
+
+ out[0] = A ^ EK[16*ROUNDS+0]; out[1] = B + EK[16*ROUNDS+1];
+ out[2] = C + EK[16*ROUNDS+2]; out[3] = D ^ EK[16*ROUNDS+3];
+ out[4] = E ^ EK[16*ROUNDS+4]; out[5] = F + EK[16*ROUNDS+5];
+ out[6] = G + EK[16*ROUNDS+6]; out[7] = H ^ EK[16*ROUNDS+7];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
- out[0] = A ^ EK[16*ROUNDS+0]; out[1] = B + EK[16*ROUNDS+1];
- out[2] = C + EK[16*ROUNDS+2]; out[3] = D ^ EK[16*ROUNDS+3];
- out[4] = E ^ EK[16*ROUNDS+4]; out[5] = F + EK[16*ROUNDS+5];
- out[6] = G + EK[16*ROUNDS+6]; out[7] = H ^ EK[16*ROUNDS+7];
}
/*
* SAFER-SK Decryption
*/
-void SAFER_SK::dec(const byte in[], byte out[]) const
+void SAFER_SK::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- byte A = in[0], B = in[1], C = in[2], D = in[3],
- E = in[4], F = in[5], G = in[6], H = in[7];
- A ^= EK[16*ROUNDS+0]; B -= EK[16*ROUNDS+1]; C -= EK[16*ROUNDS+2];
- D ^= EK[16*ROUNDS+3]; E ^= EK[16*ROUNDS+4]; F -= EK[16*ROUNDS+5];
- G -= EK[16*ROUNDS+6]; H ^= EK[16*ROUNDS+7];
- for(s32bit j = 16*(ROUNDS-1); j >= 0; j -= 16)
+ for(u32bit i = 0; i != blocks; ++i)
{
- byte T = E; E = B; B = C; C = T; T = F; F = D; D = G; G = T;
- A -= E; B -= F; C -= G; D -= H; E -= A; F -= B; G -= C; H -= D;
- A -= C; E -= G; B -= D; F -= H; C -= A; G -= E; D -= B; H -= F;
- A -= B; C -= D; E -= F; G -= H; B -= A; D -= C; F -= E; H -= G;
- A = LOG[A - EK[j+8 ] + 256]; B = EXP[B ^ EK[j+9 ]];
- C = EXP[C ^ EK[j+10]]; D = LOG[D - EK[j+11] + 256];
- E = LOG[E - EK[j+12] + 256]; F = EXP[F ^ EK[j+13]];
- G = EXP[G ^ EK[j+14]]; H = LOG[H - EK[j+15] + 256];
- A ^= EK[j+0]; B -= EK[j+1]; C -= EK[j+2]; D ^= EK[j+3];
- E ^= EK[j+4]; F -= EK[j+5]; G -= EK[j+6]; H ^= EK[j+7];
+ byte A = in[0], B = in[1], C = in[2], D = in[3],
+ E = in[4], F = in[5], G = in[6], H = in[7];
+
+ A ^= EK[16*ROUNDS+0]; B -= EK[16*ROUNDS+1]; C -= EK[16*ROUNDS+2];
+ D ^= EK[16*ROUNDS+3]; E ^= EK[16*ROUNDS+4]; F -= EK[16*ROUNDS+5];
+ G -= EK[16*ROUNDS+6]; H ^= EK[16*ROUNDS+7];
+
+ for(s32bit j = 16*(ROUNDS-1); j >= 0; j -= 16)
+ {
+ byte T = E; E = B; B = C; C = T; T = F; F = D; D = G; G = T;
+ A -= E; B -= F; C -= G; D -= H; E -= A; F -= B; G -= C; H -= D;
+ A -= C; E -= G; B -= D; F -= H; C -= A; G -= E; D -= B; H -= F;
+ A -= B; C -= D; E -= F; G -= H; B -= A; D -= C; F -= E; H -= G;
+
+ A = LOG[A - EK[j+8 ] + 256]; B = EXP[B ^ EK[j+9 ]];
+ C = EXP[C ^ EK[j+10]]; D = LOG[D - EK[j+11] + 256];
+ E = LOG[E - EK[j+12] + 256]; F = EXP[F ^ EK[j+13]];
+ G = EXP[G ^ EK[j+14]]; H = LOG[H - EK[j+15] + 256];
+
+ A ^= EK[j+0]; B -= EK[j+1]; C -= EK[j+2]; D ^= EK[j+3];
+ E ^= EK[j+4]; F -= EK[j+5]; G -= EK[j+6]; H ^= EK[j+7];
+ }
+
+ out[0] = A; out[1] = B; out[2] = C; out[3] = D;
+ out[4] = E; out[5] = F; out[6] = G; out[7] = H;
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
- out[0] = A; out[1] = B; out[2] = C; out[3] = D;
- out[4] = E; out[5] = F; out[6] = G; out[7] = H;
}
/*
diff --git a/src/block/safer/safer_sk.h b/src/block/safer/safer_sk.h
index e52c5837c..4d17bba51 100644
--- a/src/block/safer/safer_sk.h
+++ b/src/block/safer/safer_sk.h
@@ -18,19 +18,22 @@ namespace Botan {
class BOTAN_DLL SAFER_SK : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const;
BlockCipher* clone() const;
+
SAFER_SK(u32bit);
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static const byte EXP[256];
static const byte LOG[512];
static const byte BIAS[208];
static const byte KEY_INDEX[208];
+
SecureVector<byte> EK;
const u32bit ROUNDS;
};
diff --git a/src/block/seed/seed.cpp b/src/block/seed/seed.cpp
index b06a7cd77..378be16e4 100644
--- a/src/block/seed/seed.cpp
+++ b/src/block/seed/seed.cpp
@@ -22,69 +22,81 @@ u32bit SEED::G_FUNC::operator()(u32bit X) const
/*
* SEED Encryption
*/
-void SEED::enc(const byte in[], byte out[]) const
+void SEED::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit B0 = load_be<u32bit>(in, 0);
- u32bit B1 = load_be<u32bit>(in, 1);
- u32bit B2 = load_be<u32bit>(in, 2);
- u32bit B3 = load_be<u32bit>(in, 3);
-
- G_FUNC G;
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- u32bit T0, T1;
-
- T0 = B2 ^ K[2*j];
- T1 = G(B2 ^ B3 ^ K[2*j+1]);
- T0 = G(T1 + T0);
- T1 = G(T1 + T0);
- B1 ^= T1;
- B0 ^= T0 + T1;
-
- T0 = B0 ^ K[2*j+2];
- T1 = G(B0 ^ B1 ^ K[2*j+3]);
- T0 = G(T1 + T0);
- T1 = G(T1 + T0);
- B3 ^= T1;
- B2 ^= T0 + T1;
+ u32bit B0 = load_be<u32bit>(in, 0);
+ u32bit B1 = load_be<u32bit>(in, 1);
+ u32bit B2 = load_be<u32bit>(in, 2);
+ u32bit B3 = load_be<u32bit>(in, 3);
+
+ G_FUNC G;
+
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit T0, T1;
+
+ T0 = B2 ^ K[2*j];
+ T1 = G(B2 ^ B3 ^ K[2*j+1]);
+ T0 = G(T1 + T0);
+ T1 = G(T1 + T0);
+ B1 ^= T1;
+ B0 ^= T0 + T1;
+
+ T0 = B0 ^ K[2*j+2];
+ T1 = G(B0 ^ B1 ^ K[2*j+3]);
+ T0 = G(T1 + T0);
+ T1 = G(T1 + T0);
+ B3 ^= T1;
+ B2 ^= T0 + T1;
+ }
+
+ store_be(out, B2, B3, B0, B1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
-
- store_be(out, B2, B3, B0, B1);
}
/*
* SEED Decryption
*/
-void SEED::dec(const byte in[], byte out[]) const
+void SEED::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit B0 = load_be<u32bit>(in, 0);
- u32bit B1 = load_be<u32bit>(in, 1);
- u32bit B2 = load_be<u32bit>(in, 2);
- u32bit B3 = load_be<u32bit>(in, 3);
-
- G_FUNC G;
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- u32bit T0, T1;
-
- T0 = B2 ^ K[30-2*j];
- T1 = G(B2 ^ B3 ^ K[31-2*j]);
- T0 = G(T1 + T0);
- T1 = G(T1 + T0);
- B1 ^= T1;
- B0 ^= T0 + T1;
-
- T0 = B0 ^ K[28-2*j];
- T1 = G(B0 ^ B1 ^ K[29-2*j]);
- T0 = G(T1 + T0);
- T1 = G(T1 + T0);
- B3 ^= T1;
- B2 ^= T0 + T1;
+ u32bit B0 = load_be<u32bit>(in, 0);
+ u32bit B1 = load_be<u32bit>(in, 1);
+ u32bit B2 = load_be<u32bit>(in, 2);
+ u32bit B3 = load_be<u32bit>(in, 3);
+
+ G_FUNC G;
+
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit T0, T1;
+
+ T0 = B2 ^ K[30-2*j];
+ T1 = G(B2 ^ B3 ^ K[31-2*j]);
+ T0 = G(T1 + T0);
+ T1 = G(T1 + T0);
+ B1 ^= T1;
+ B0 ^= T0 + T1;
+
+ T0 = B0 ^ K[28-2*j];
+ T1 = G(B0 ^ B1 ^ K[29-2*j]);
+ T0 = G(T1 + T0);
+ T1 = G(T1 + T0);
+ B3 ^= T1;
+ B2 ^= T0 + T1;
+ }
+
+ store_be(out, B2, B3, B0, B1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
-
- store_be(out, B2, B3, B0, B1);
}
/*
diff --git a/src/block/seed/seed.h b/src/block/seed/seed.h
index 54c25d580..5a5a512e7 100644
--- a/src/block/seed/seed.h
+++ b/src/block/seed/seed.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL SEED : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { K.clear(); }
std::string name() const { return "SEED"; }
BlockCipher* clone() const { return new SEED; }
+
SEED() : BlockCipher(16, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
class G_FUNC
diff --git a/src/block/serpent/serpent.cpp b/src/block/serpent/serpent.cpp
index df7592fea..2fa27308f 100644
--- a/src/block/serpent/serpent.cpp
+++ b/src/block/serpent/serpent.cpp
@@ -243,93 +243,105 @@ inline void i_transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3)
/*
* Serpent Encryption
*/
-void Serpent::enc(const byte in[], byte out[]) const
+void Serpent::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit B0 = load_le<u32bit>(in, 0);
- u32bit B1 = load_le<u32bit>(in, 1);
- u32bit B2 = load_le<u32bit>(in, 2);
- u32bit B3 = load_le<u32bit>(in, 3);
-
- key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
- key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
-
- store_le(out, B0, B1, B2, B3);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit B0 = load_le<u32bit>(in, 0);
+ u32bit B1 = load_le<u32bit>(in, 1);
+ u32bit B2 = load_le<u32bit>(in, 2);
+ u32bit B3 = load_le<u32bit>(in, 3);
+
+ key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
+
+ store_le(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Serpent Decryption
*/
-void Serpent::dec(const byte in[], byte out[]) const
+void Serpent::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit B0 = load_le<u32bit>(in, 0);
- u32bit B1 = load_le<u32bit>(in, 1);
- u32bit B2 = load_le<u32bit>(in, 2);
- u32bit B3 = load_le<u32bit>(in, 3);
-
- key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3);
- i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3);
-
- store_le(out, B0, B1, B2, B3);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u32bit B0 = load_le<u32bit>(in, 0);
+ u32bit B1 = load_le<u32bit>(in, 1);
+ u32bit B2 = load_le<u32bit>(in, 2);
+ u32bit B3 = load_le<u32bit>(in, 3);
+
+ key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3);
+
+ store_le(out, B0, B1, B2, B3);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h
index 5b9be257f..d919c3008 100644
--- a/src/block/serpent/serpent.h
+++ b/src/block/serpent/serpent.h
@@ -18,13 +18,14 @@ namespace Botan {
class BOTAN_DLL Serpent : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { round_key.clear(); }
std::string name() const { return "Serpent"; }
BlockCipher* clone() const { return new Serpent; }
Serpent() : BlockCipher(16, 16, 32, 8) {}
protected:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 132> round_key;
diff --git a/src/block/serpent_ia32/info.txt b/src/block/serpent_ia32/info.txt
index 13b171fe9..ea0506299 100644
--- a/src/block/serpent_ia32/info.txt
+++ b/src/block/serpent_ia32/info.txt
@@ -23,6 +23,7 @@ icc
<os>
linux
freebsd
+dragonfly
netbsd
openbsd
solaris
diff --git a/src/block/serpent_ia32/serp_ia32.cpp b/src/block/serpent_ia32/serp_ia32.cpp
index 37dd4e637..997bec2fc 100644
--- a/src/block/serpent_ia32/serp_ia32.cpp
+++ b/src/block/serpent_ia32/serp_ia32.cpp
@@ -21,17 +21,27 @@ void botan_serpent_ia32_key_schedule(u32bit[140]);
/*
* Serpent Encryption
*/
-void Serpent_IA32::enc(const byte in[], byte out[]) const
+void Serpent_IA32::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- botan_serpent_ia32_encrypt(in, out, round_key);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ botan_serpent_ia32_encrypt(in, out, round_key);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Serpent Decryption
*/
-void Serpent_IA32::dec(const byte in[], byte out[]) const
+void Serpent_IA32::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- botan_serpent_ia32_decrypt(in, out, round_key);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ botan_serpent_ia32_decrypt(in, out, round_key);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/serpent_ia32/serp_ia32.h b/src/block/serpent_ia32/serp_ia32.h
index 565e9889d..dc6beaf13 100644
--- a/src/block/serpent_ia32/serp_ia32.h
+++ b/src/block/serpent_ia32/serp_ia32.h
@@ -18,10 +18,11 @@ namespace Botan {
class BOTAN_DLL Serpent_IA32 : public Serpent
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
BlockCipher* clone() const { return new Serpent_IA32; }
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
};
diff --git a/src/block/serpent_ia32/serp_ia32_imp.S b/src/block/serpent_ia32/serp_ia32_imp.S
index ddfcc7806..9e50f8cdc 100644
--- a/src/block/serpent_ia32/serp_ia32_imp.S
+++ b/src/block/serpent_ia32/serp_ia32_imp.S
@@ -1,7 +1,9 @@
-/*************************************************
-* Serpent Source File *
-* (C) 1999-2007 Jack Lloyd *
-*************************************************/
+/*
+* Serpent Source File
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
#include <botan/asm_macr.h>
@@ -436,9 +438,9 @@ START_LISTING(serp_ia32.S)
XOR(C, ARRAY4(EDI, (4*N+2))) ; \
XOR(D, ARRAY4(EDI, (4*N+3))) ;
-/*************************************************
-* Serpent Encryption *
-*************************************************/
+/*
+* Serpent Encryption
+*/
START_FUNCTION(botan_serpent_ia32_encrypt)
SPILL_REGS()
#define PUSHED 4
@@ -507,9 +509,9 @@ START_FUNCTION(botan_serpent_ia32_encrypt)
#undef PUSHED
END_FUNCTION(botan_serpent_ia32_encrypt)
-/*************************************************
-* Serpent Decryption *
-*************************************************/
+/*
+* Serpent Decryption
+*/
START_FUNCTION(botan_serpent_ia32_decrypt)
SPILL_REGS()
#define PUSHED 4
@@ -578,9 +580,9 @@ START_FUNCTION(botan_serpent_ia32_decrypt)
#undef PUSHED
END_FUNCTION(botan_serpent_ia32_decrypt)
-/*************************************************
-* Serpent Key Schedule *
-*************************************************/
+/*
+* Serpent Key Schedule
+*/
START_FUNCTION(botan_serpent_ia32_key_schedule)
SPILL_REGS()
#define PUSHED 4
diff --git a/src/block/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt
new file mode 100644
index 000000000..b00ab6e88
--- /dev/null
+++ b/src/block/serpent_sse2/info.txt
@@ -0,0 +1,16 @@
+realname "Serpent (SSE2)"
+
+define SERPENT_SSE2
+
+load_on auto
+
+<add>
+serp_sse2.cpp
+serp_sse2.h
+serp_sse2_sbox.h
+</add>
+
+<requires>
+serpent
+sse2_eng
+</requires>
diff --git a/src/block/serpent_sse2/serp_sse2.cpp b/src/block/serpent_sse2/serp_sse2.cpp
new file mode 100644
index 000000000..c51bb69ab
--- /dev/null
+++ b/src/block/serpent_sse2/serp_sse2.cpp
@@ -0,0 +1,240 @@
+/*
+* Serpent (SSE2)
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/serp_sse2.h>
+#include <botan/serp_sse2_sbox.h>
+#include <botan/loadstor.h>
+#include <emmintrin.h>
+
+namespace Botan {
+
+namespace {
+
+#define key_xor(round, B0, B1, B2, B3) \
+ do { \
+ __m128i key = _mm_loadu_si128(keys + round); \
+ B0 = _mm_xor_si128(B0, _mm_shuffle_epi32(key, _MM_SHUFFLE(0,0,0,0))); \
+ B1 = _mm_xor_si128(B1, _mm_shuffle_epi32(key, _MM_SHUFFLE(1,1,1,1))); \
+ B2 = _mm_xor_si128(B2, _mm_shuffle_epi32(key, _MM_SHUFFLE(2,2,2,2))); \
+ B3 = _mm_xor_si128(B3, _mm_shuffle_epi32(key, _MM_SHUFFLE(3,3,3,3))); \
+ } while(0);
+
+/*
+* Serpent's linear transformations
+*/
+#define rotate_left_m128(vec, rot) \
+ _mm_or_si128(_mm_slli_epi32(vec, rot), _mm_srli_epi32(vec, 32-rot))
+
+#define rotate_right_m128(vec, rot) \
+ _mm_or_si128(_mm_srli_epi32(vec, rot), _mm_slli_epi32(vec, 32-rot))
+
+#define transform(B0, B1, B2, B3) \
+ do { \
+ B0 = rotate_left_m128(B0, 13); \
+ B2 = rotate_left_m128(B2, 3); \
+ B1 = _mm_xor_si128(B1, _mm_xor_si128(B0, B2)); \
+ B3 = _mm_xor_si128(B3, _mm_xor_si128(B2, _mm_slli_epi32(B0, 3))); \
+ B1 = rotate_left_m128(B1, 1); \
+ B3 = rotate_left_m128(B3, 7); \
+ B0 = _mm_xor_si128(B0, _mm_xor_si128(B1, B3)); \
+ B2 = _mm_xor_si128(B2, _mm_xor_si128(B3, _mm_slli_epi32(B1, 7))); \
+ B0 = rotate_left_m128(B0, 5); \
+ B2 = rotate_left_m128(B2, 22); \
+ } while(0);
+
+#define i_transform(B0, B1, B2, B3) \
+ do { \
+ B2 = rotate_right_m128(B2, 22); \
+ B0 = rotate_right_m128(B0, 5); \
+ B2 = _mm_xor_si128(B2, _mm_xor_si128(B3, _mm_slli_epi32(B1, 7))); \
+ B0 = _mm_xor_si128(B0, _mm_xor_si128(B1, B3)); \
+ B3 = rotate_right_m128(B3, 7); \
+ B1 = rotate_right_m128(B1, 1); \
+ B3 = _mm_xor_si128(B3, _mm_xor_si128(B2, _mm_slli_epi32(B0, 3))); \
+ B1 = _mm_xor_si128(B1, _mm_xor_si128(B0, B2)); \
+ B2 = rotate_right_m128(B2, 3); \
+ B0 = rotate_right_m128(B0, 13); \
+ } while(0);
+
+/*
+* 4x4 SSE2 integer matrix transpose
+*/
+#define transpose(B0, B1, B2, B3) \
+ do { \
+ __m128i T0 = _mm_unpacklo_epi32(B0, B1); \
+ __m128i T1 = _mm_unpacklo_epi32(B2, B3); \
+ __m128i T2 = _mm_unpackhi_epi32(B0, B1); \
+ __m128i T3 = _mm_unpackhi_epi32(B2, B3); \
+ B0 = _mm_unpacklo_epi64(T0, T1); \
+ B1 = _mm_unpackhi_epi64(T0, T1); \
+ B2 = _mm_unpacklo_epi64(T2, T3); \
+ B3 = _mm_unpackhi_epi64(T2, T3); \
+ } while(0);
+
+/*
+* SSE2 Serpent Encryption of 4 blocks in parallel
+*/
+void serpent_encrypt_4(const byte in[64],
+ byte out[64],
+ const u32bit keys_32[132])
+ {
+ const __m128i all_ones = _mm_set1_epi8(0xFF);
+
+ const __m128i* keys = (const __m128i*)(keys_32);
+ __m128i* out_mm = (__m128i*)(out);
+ __m128i* in_mm = (__m128i*)(in);
+
+ __m128i B0 = _mm_loadu_si128(in_mm);
+ __m128i B1 = _mm_loadu_si128(in_mm + 1);
+ __m128i B2 = _mm_loadu_si128(in_mm + 2);
+ __m128i B3 = _mm_loadu_si128(in_mm + 3);
+
+ transpose(B0, B1, B2, B3);
+
+ key_xor( 0,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 1,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 2,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 3,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 4,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 5,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 6,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 7,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+
+ key_xor( 8,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor( 9,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(10,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(11,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(12,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(13,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(14,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(15,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+
+ key_xor(16,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(17,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(18,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(19,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(20,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(21,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(22,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(23,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+
+ key_xor(24,B0,B1,B2,B3); SBoxE1(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(25,B0,B1,B2,B3); SBoxE2(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(26,B0,B1,B2,B3); SBoxE3(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(27,B0,B1,B2,B3); SBoxE4(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(28,B0,B1,B2,B3); SBoxE5(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(29,B0,B1,B2,B3); SBoxE6(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(30,B0,B1,B2,B3); SBoxE7(B0,B1,B2,B3); transform(B0,B1,B2,B3);
+ key_xor(31,B0,B1,B2,B3); SBoxE8(B0,B1,B2,B3); key_xor(32,B0,B1,B2,B3);
+
+ transpose(B0, B1, B2, B3);
+
+ _mm_storeu_si128(out_mm , B0);
+ _mm_storeu_si128(out_mm + 1, B1);
+ _mm_storeu_si128(out_mm + 2, B2);
+ _mm_storeu_si128(out_mm + 3, B3);
+ }
+
+/*
+* SSE2 Serpent Decryption of 4 blocks in parallel
+*/
+void serpent_decrypt_4(const byte in[64],
+ byte out[64],
+ const u32bit keys_32[132])
+ {
+ const __m128i all_ones = _mm_set1_epi8(0xFF);
+
+ const __m128i* keys = (const __m128i*)(keys_32);
+ __m128i* out_mm = (__m128i*)(out);
+ __m128i* in_mm = (__m128i*)(in);
+
+ __m128i B0 = _mm_loadu_si128(in_mm);
+ __m128i B1 = _mm_loadu_si128(in_mm + 1);
+ __m128i B2 = _mm_loadu_si128(in_mm + 2);
+ __m128i B3 = _mm_loadu_si128(in_mm + 3);
+
+ transpose(B0, B1, B2, B3);
+
+ key_xor(32,B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(31,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(30,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(29,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(28,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(27,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(26,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(25,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(24,B0,B1,B2,B3);
+
+ i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(23,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(22,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(21,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(20,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(19,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(18,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor(17,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor(16,B0,B1,B2,B3);
+
+ i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor(15,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor(14,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor(13,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor(12,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor(11,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor(10,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 9,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 8,B0,B1,B2,B3);
+
+ i_transform(B0,B1,B2,B3); SBoxD8(B0,B1,B2,B3); key_xor( 7,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD7(B0,B1,B2,B3); key_xor( 6,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD6(B0,B1,B2,B3); key_xor( 5,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD5(B0,B1,B2,B3); key_xor( 4,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD4(B0,B1,B2,B3); key_xor( 3,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD3(B0,B1,B2,B3); key_xor( 2,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD2(B0,B1,B2,B3); key_xor( 1,B0,B1,B2,B3);
+ i_transform(B0,B1,B2,B3); SBoxD1(B0,B1,B2,B3); key_xor( 0,B0,B1,B2,B3);
+
+ transpose(B0, B1, B2, B3);
+
+ _mm_storeu_si128(out_mm , B0);
+ _mm_storeu_si128(out_mm + 1, B1);
+ _mm_storeu_si128(out_mm + 2, B2);
+ _mm_storeu_si128(out_mm + 3, B3);
+ }
+
+}
+
+/*
+* Serpent Encryption
+*/
+void Serpent_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 4)
+ {
+ serpent_encrypt_4(in, out, this->round_key);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
+ }
+
+ Serpent::encrypt_n(in, out, blocks);
+ }
+
+/*
+* Serpent Decryption
+*/
+void Serpent_SSE2::decrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 4)
+ {
+ serpent_decrypt_4(in, out, this->round_key);
+ in += 4 * BLOCK_SIZE;
+ out += 4 * BLOCK_SIZE;
+ blocks -= 4;
+ }
+
+ Serpent::decrypt_n(in, out, blocks);
+ }
+
+}
diff --git a/src/block/serpent_sse2/serp_sse2.h b/src/block/serpent_sse2/serp_sse2.h
new file mode 100644
index 000000000..f1e5c2028
--- /dev/null
+++ b/src/block/serpent_sse2/serp_sse2.h
@@ -0,0 +1,29 @@
+/*
+* Serpent (SSE2)
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SERPENT_SSE2_H__
+#define BOTAN_SERPENT_SSE2_H__
+
+#include <botan/serpent.h>
+
+namespace Botan {
+
+/*
+* Serpent
+*/
+class BOTAN_DLL Serpent_SSE2 : public Serpent
+ {
+ public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
+ BlockCipher* clone() const { return new Serpent_SSE2; }
+ };
+
+}
+
+#endif
diff --git a/src/block/serpent_sse2/serp_sse2_sbox.h b/src/block/serpent_sse2/serp_sse2_sbox.h
new file mode 100644
index 000000000..40c552e87
--- /dev/null
+++ b/src/block/serpent_sse2/serp_sse2_sbox.h
@@ -0,0 +1,434 @@
+/*
+* Serpent Sboxes in SSE2 form
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef SERPENT_SSE2_SBOXES_H__
+#define SERPENT_SSE2_SBOXES_H__
+
+#define SBoxE1(B0, B1, B2, B3) \
+ do { \
+ B3 = _mm_xor_si128(B3, B0); \
+ __m128i B4 = B1; \
+ B1 = _mm_and_si128(B1, B3); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B1 = _mm_xor_si128(B1, B0); \
+ B0 = _mm_or_si128(B0, B3); \
+ B0 = _mm_xor_si128(B0, B4); \
+ B4 = _mm_xor_si128(B4, B3); \
+ B3 = _mm_xor_si128(B3, B2); \
+ B2 = _mm_or_si128(B2, B1); \
+ B2 = _mm_xor_si128(B2, B4); \
+ B4 = _mm_xor_si128(B4, all_ones); \
+ B4 = _mm_or_si128(B4, B1); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B1 = _mm_xor_si128(B1, B4); \
+ B3 = _mm_or_si128(B3, B0); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B4 = _mm_xor_si128(B4, B3); \
+ B3 = B0; \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE2(B0, B1, B2, B3) \
+ do { \
+ B0 = _mm_xor_si128(B0, all_ones); \
+ B2 = _mm_xor_si128(B2, all_ones); \
+ __m128i B4 = B0; \
+ B0 = _mm_and_si128(B0, B1); \
+ B2 = _mm_xor_si128(B2, B0); \
+ B0 = _mm_or_si128(B0, B3); \
+ B3 = _mm_xor_si128(B3, B2); \
+ B1 = _mm_xor_si128(B1, B0); \
+ B0 = _mm_xor_si128(B0, B4); \
+ B4 = _mm_or_si128(B4, B1); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B2 = _mm_or_si128(B2, B0); \
+ B2 = _mm_and_si128(B2, B4); \
+ B0 = _mm_xor_si128(B0, B1); \
+ B1 = _mm_and_si128(B1, B2); \
+ B1 = _mm_xor_si128(B1, B0); \
+ B0 = _mm_and_si128(B0, B2); \
+ B4 = _mm_xor_si128(B4, B0); \
+ B0 = B2; \
+ B2 = B3; \
+ B3 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE3(B0, B1, B2, B3) \
+ do { \
+ __m128i B4 = B0; \
+ B0 = _mm_and_si128(B0, B2); \
+ B0 = _mm_xor_si128(B0, B3); \
+ B2 = _mm_xor_si128(B2, B1); \
+ B2 = _mm_xor_si128(B2, B0); \
+ B3 = _mm_or_si128(B3, B4); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B1 = B3; \
+ B3 = _mm_or_si128(B3, B4); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B0 = _mm_and_si128(B0, B1); \
+ B4 = _mm_xor_si128(B4, B0); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B1 = _mm_xor_si128(B1, B4); \
+ B4 = _mm_xor_si128(B4, all_ones); \
+ B0 = B2; \
+ B2 = B1; \
+ B1 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxE4(B0, B1, B2, B3) \
+ do { \
+ __m128i B4 = B0; \
+ B0 = _mm_or_si128(B0, B3); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B1 = _mm_and_si128(B1, B4); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = _mm_xor_si128(B2, B3); \
+ B3 = _mm_and_si128(B3, B0); \
+ B4 = _mm_or_si128(B4, B1); \
+ B3 = _mm_xor_si128(B3, B4); \
+ B0 = _mm_xor_si128(B0, B1); \
+ B4 = _mm_and_si128(B4, B0); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B1 = _mm_or_si128(B1, B0); \
+ B1 = _mm_xor_si128(B1, B2); \
+ B0 = _mm_xor_si128(B0, B3); \
+ B2 = B1; \
+ B1 = _mm_or_si128(B1, B3); \
+ B0 = _mm_xor_si128(B0, B1); \
+ B1 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxE5(B0, B1, B2, B3) \
+ do { \
+ B1 = _mm_xor_si128(B1, B3); \
+ B3 = _mm_xor_si128(B3, all_ones); \
+ B2 = _mm_xor_si128(B2, B3); \
+ B3 = _mm_xor_si128(B3, B0); \
+ __m128i B4 = B1; \
+ B1 = _mm_and_si128(B1, B3); \
+ B1 = _mm_xor_si128(B1, B2); \
+ B4 = _mm_xor_si128(B4, B3); \
+ B0 = _mm_xor_si128(B0, B4); \
+ B2 = _mm_and_si128(B2, B4); \
+ B2 = _mm_xor_si128(B2, B0); \
+ B0 = _mm_and_si128(B0, B1); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B4 = _mm_or_si128(B4, B1); \
+ B4 = _mm_xor_si128(B4, B0); \
+ B0 = _mm_or_si128(B0, B3); \
+ B0 = _mm_xor_si128(B0, B2); \
+ B2 = _mm_and_si128(B2, B3); \
+ B0 = _mm_xor_si128(B0, all_ones); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = B0; \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE6(B0, B1, B2, B3) \
+ do { \
+ B0 = _mm_xor_si128(B0, B1); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B3 = _mm_xor_si128(B3, all_ones); \
+ __m128i B4 = B1; \
+ B1 = _mm_and_si128(B1, B0); \
+ B2 = _mm_xor_si128(B2, B3); \
+ B1 = _mm_xor_si128(B1, B2); \
+ B2 = _mm_or_si128(B2, B4); \
+ B4 = _mm_xor_si128(B4, B3); \
+ B3 = _mm_and_si128(B3, B1); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B4 = _mm_xor_si128(B4, B1); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = _mm_xor_si128(B2, B0); \
+ B0 = _mm_and_si128(B0, B3); \
+ B2 = _mm_xor_si128(B2, all_ones); \
+ B0 = _mm_xor_si128(B0, B4); \
+ B4 = _mm_or_si128(B4, B3); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = B0; \
+ B0 = B1; \
+ B1 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxE7(B0, B1, B2, B3) \
+ do { \
+ B2 = _mm_xor_si128(B2, all_ones); \
+ __m128i B4 = B3; \
+ B3 = _mm_and_si128(B3, B0); \
+ B0 = _mm_xor_si128(B0, B4); \
+ B3 = _mm_xor_si128(B3, B2); \
+ B2 = _mm_or_si128(B2, B4); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B2 = _mm_xor_si128(B2, B0); \
+ B0 = _mm_or_si128(B0, B1); \
+ B2 = _mm_xor_si128(B2, B1); \
+ B4 = _mm_xor_si128(B4, B0); \
+ B0 = _mm_or_si128(B0, B3); \
+ B0 = _mm_xor_si128(B0, B2); \
+ B4 = _mm_xor_si128(B4, B3); \
+ B4 = _mm_xor_si128(B4, B0); \
+ B3 = _mm_xor_si128(B3, all_ones); \
+ B2 = _mm_and_si128(B2, B4); \
+ B3 = _mm_xor_si128(B3, B2); \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxE8(B0, B1, B2, B3) \
+ do { \
+ __m128i B4 = B1; \
+ B1 = _mm_or_si128(B1, B2); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = _mm_xor_si128(B2, B1); \
+ B3 = _mm_or_si128(B3, B4); \
+ B3 = _mm_and_si128(B3, B0); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B1 = _mm_or_si128(B1, B4); \
+ B1 = _mm_xor_si128(B1, B0); \
+ B0 = _mm_or_si128(B0, B4); \
+ B0 = _mm_xor_si128(B0, B2); \
+ B1 = _mm_xor_si128(B1, B4); \
+ B2 = _mm_xor_si128(B2, B1); \
+ B1 = _mm_and_si128(B1, B0); \
+ B1 = _mm_xor_si128(B1, B4); \
+ B2 = _mm_xor_si128(B2, all_ones); \
+ B2 = _mm_or_si128(B2, B0); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = B1; \
+ B1 = B3; \
+ B3 = B0; \
+ B0 = B4; \
+ } while(0);
+
+#define SBoxD1(B0, B1, B2, B3) \
+ do \
+ { \
+ B2 = _mm_xor_si128(B2, all_ones); \
+ __m128i B4 = B1; \
+ B1 = _mm_or_si128(B1, B0); \
+ B4 = _mm_xor_si128(B4, all_ones); \
+ B1 = _mm_xor_si128(B1, B2); \
+ B2 = _mm_or_si128(B2, B4); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B0 = _mm_xor_si128(B0, B4); \
+ B2 = _mm_xor_si128(B2, B0); \
+ B0 = _mm_and_si128(B0, B3); \
+ B4 = _mm_xor_si128(B4, B0); \
+ B0 = _mm_or_si128(B0, B1); \
+ B0 = _mm_xor_si128(B0, B2); \
+ B3 = _mm_xor_si128(B3, B4); \
+ B2 = _mm_xor_si128(B2, B1); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B2 = _mm_and_si128(B2, B3); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxD2(B0, B1, B2, B3) \
+ do \
+ { \
+ __m128i B4 = B1; \
+ B1 = _mm_xor_si128(B1, B3); \
+ B3 = _mm_and_si128(B3, B1); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B0 = _mm_or_si128(B0, B1); \
+ B2 = _mm_xor_si128(B2, B3); \
+ B0 = _mm_xor_si128(B0, B4); \
+ B0 = _mm_or_si128(B0, B2); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B0 = _mm_xor_si128(B0, B1); \
+ B1 = _mm_or_si128(B1, B3); \
+ B1 = _mm_xor_si128(B1, B0); \
+ B4 = _mm_xor_si128(B4, all_ones); \
+ B4 = _mm_xor_si128(B4, B1); \
+ B1 = _mm_or_si128(B1, B0); \
+ B1 = _mm_xor_si128(B1, B0); \
+ B1 = _mm_or_si128(B1, B4); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B1 = B0; \
+ B0 = B4; \
+ B4 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD3(B0, B1, B2, B3) \
+ do \
+ { \
+ B2 = _mm_xor_si128(B2, B3); \
+ B3 = _mm_xor_si128(B3, B0); \
+ __m128i B4 = B3; \
+ B3 = _mm_and_si128(B3, B2); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B1 = _mm_or_si128(B1, B2); \
+ B1 = _mm_xor_si128(B1, B4); \
+ B4 = _mm_and_si128(B4, B3); \
+ B2 = _mm_xor_si128(B2, B3); \
+ B4 = _mm_and_si128(B4, B0); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = _mm_and_si128(B2, B1); \
+ B2 = _mm_or_si128(B2, B0); \
+ B3 = _mm_xor_si128(B3, all_ones); \
+ B2 = _mm_xor_si128(B2, B3); \
+ B0 = _mm_xor_si128(B0, B3); \
+ B0 = _mm_and_si128(B0, B1); \
+ B3 = _mm_xor_si128(B3, B4); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxD4(B0, B1, B2, B3) \
+ do \
+ { \
+ __m128i B4 = B2; \
+ B2 = _mm_xor_si128(B2, B1); \
+ B0 = _mm_xor_si128(B0, B2); \
+ B4 = _mm_and_si128(B4, B2); \
+ B4 = _mm_xor_si128(B4, B0); \
+ B0 = _mm_and_si128(B0, B1); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B3 = _mm_or_si128(B3, B4); \
+ B2 = _mm_xor_si128(B2, B3); \
+ B0 = _mm_xor_si128(B0, B3); \
+ B1 = _mm_xor_si128(B1, B4); \
+ B3 = _mm_and_si128(B3, B2); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B1 = _mm_xor_si128(B1, B0); \
+ B1 = _mm_or_si128(B1, B2); \
+ B0 = _mm_xor_si128(B0, B3); \
+ B1 = _mm_xor_si128(B1, B4); \
+ B0 = _mm_xor_si128(B0, B1); \
+ B4 = B0; \
+ B0 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD5(B0, B1, B2, B3) \
+ do \
+ { \
+ __m128i B4 = B2; \
+ B2 = _mm_and_si128(B2, B3); \
+ B2 = _mm_xor_si128(B2, B1); \
+ B1 = _mm_or_si128(B1, B3); \
+ B1 = _mm_and_si128(B1, B0); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B4 = _mm_xor_si128(B4, B1); \
+ B1 = _mm_and_si128(B1, B2); \
+ B0 = _mm_xor_si128(B0, all_ones); \
+ B3 = _mm_xor_si128(B3, B4); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B3 = _mm_and_si128(B3, B0); \
+ B3 = _mm_xor_si128(B3, B2); \
+ B0 = _mm_xor_si128(B0, B1); \
+ B2 = _mm_and_si128(B2, B0); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B2 = _mm_xor_si128(B2, B4); \
+ B2 = _mm_or_si128(B2, B3); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B2 = _mm_xor_si128(B2, B1); \
+ B1 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD6(B0, B1, B2, B3) \
+ do \
+ { \
+ B1 = _mm_xor_si128(B1, all_ones); \
+ __m128i B4 = B3; \
+ B2 = _mm_xor_si128(B2, B1); \
+ B3 = _mm_or_si128(B3, B0); \
+ B3 = _mm_xor_si128(B3, B2); \
+ B2 = _mm_or_si128(B2, B1); \
+ B2 = _mm_and_si128(B2, B0); \
+ B4 = _mm_xor_si128(B4, B3); \
+ B2 = _mm_xor_si128(B2, B4); \
+ B4 = _mm_or_si128(B4, B0); \
+ B4 = _mm_xor_si128(B4, B1); \
+ B1 = _mm_and_si128(B1, B2); \
+ B1 = _mm_xor_si128(B1, B3); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B3 = _mm_and_si128(B3, B4); \
+ B4 = _mm_xor_si128(B4, B1); \
+ B3 = _mm_xor_si128(B3, B4); \
+ B4 = _mm_xor_si128(B4, all_ones); \
+ B3 = _mm_xor_si128(B3, B0); \
+ B0 = B1; \
+ B1 = B4; \
+ B4 = B3; \
+ B3 = B2; \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxD7(B0, B1, B2, B3) \
+ do \
+ { \
+ B0 = _mm_xor_si128(B0, B2); \
+ __m128i B4 = B2; \
+ B2 = _mm_and_si128(B2, B0); \
+ B4 = _mm_xor_si128(B4, B3); \
+ B2 = _mm_xor_si128(B2, all_ones); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B2 = _mm_xor_si128(B2, B3); \
+ B4 = _mm_or_si128(B4, B0); \
+ B0 = _mm_xor_si128(B0, B2); \
+ B3 = _mm_xor_si128(B3, B4); \
+ B4 = _mm_xor_si128(B4, B1); \
+ B1 = _mm_and_si128(B1, B3); \
+ B1 = _mm_xor_si128(B1, B0); \
+ B0 = _mm_xor_si128(B0, B3); \
+ B0 = _mm_or_si128(B0, B2); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B4 = _mm_xor_si128(B4, B0); \
+ B0 = B1; \
+ B1 = B2; \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxD8(B0, B1, B2, B3) \
+ do \
+ { \
+ __m128i B4 = B2; \
+ B2 = _mm_xor_si128(B2, B0); \
+ B0 = _mm_and_si128(B0, B3); \
+ B4 = _mm_or_si128(B4, B3); \
+ B2 = _mm_xor_si128(B2, all_ones); \
+ B3 = _mm_xor_si128(B3, B1); \
+ B1 = _mm_or_si128(B1, B0); \
+ B0 = _mm_xor_si128(B0, B2); \
+ B2 = _mm_and_si128(B2, B4); \
+ B3 = _mm_and_si128(B3, B4); \
+ B1 = _mm_xor_si128(B1, B2); \
+ B2 = _mm_xor_si128(B2, B0); \
+ B0 = _mm_or_si128(B0, B2); \
+ B4 = _mm_xor_si128(B4, B1); \
+ B0 = _mm_xor_si128(B0, B3); \
+ B3 = _mm_xor_si128(B3, B4); \
+ B4 = _mm_or_si128(B4, B0); \
+ B3 = _mm_xor_si128(B3, B2); \
+ B4 = _mm_xor_si128(B4, B2); \
+ B2 = B1; \
+ B1 = B0; \
+ B0 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#endif
diff --git a/src/block/skipjack/skipjack.cpp b/src/block/skipjack/skipjack.cpp
index f5ffc861e..6c308c0f8 100644
--- a/src/block/skipjack/skipjack.cpp
+++ b/src/block/skipjack/skipjack.cpp
@@ -13,51 +13,63 @@ namespace Botan {
/*
* Skipjack Encryption
*/
-void Skipjack::enc(const byte in[], byte out[]) const
+void Skipjack::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit W1 = load_le<u16bit>(in, 3);
- u16bit W2 = load_le<u16bit>(in, 2);
- u16bit W3 = load_le<u16bit>(in, 1);
- u16bit W4 = load_le<u16bit>(in, 0);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u16bit W1 = load_le<u16bit>(in, 3);
+ u16bit W2 = load_le<u16bit>(in, 2);
+ u16bit W3 = load_le<u16bit>(in, 1);
+ u16bit W4 = load_le<u16bit>(in, 0);
- step_A(W1,W4, 1); step_A(W4,W3, 2); step_A(W3,W2, 3); step_A(W2,W1, 4);
- step_A(W1,W4, 5); step_A(W4,W3, 6); step_A(W3,W2, 7); step_A(W2,W1, 8);
+ step_A(W1,W4, 1); step_A(W4,W3, 2); step_A(W3,W2, 3); step_A(W2,W1, 4);
+ step_A(W1,W4, 5); step_A(W4,W3, 6); step_A(W3,W2, 7); step_A(W2,W1, 8);
- step_B(W1,W2, 9); step_B(W4,W1,10); step_B(W3,W4,11); step_B(W2,W3,12);
- step_B(W1,W2,13); step_B(W4,W1,14); step_B(W3,W4,15); step_B(W2,W3,16);
+ step_B(W1,W2, 9); step_B(W4,W1,10); step_B(W3,W4,11); step_B(W2,W3,12);
+ step_B(W1,W2,13); step_B(W4,W1,14); step_B(W3,W4,15); step_B(W2,W3,16);
- step_A(W1,W4,17); step_A(W4,W3,18); step_A(W3,W2,19); step_A(W2,W1,20);
- step_A(W1,W4,21); step_A(W4,W3,22); step_A(W3,W2,23); step_A(W2,W1,24);
+ step_A(W1,W4,17); step_A(W4,W3,18); step_A(W3,W2,19); step_A(W2,W1,20);
+ step_A(W1,W4,21); step_A(W4,W3,22); step_A(W3,W2,23); step_A(W2,W1,24);
- step_B(W1,W2,25); step_B(W4,W1,26); step_B(W3,W4,27); step_B(W2,W3,28);
- step_B(W1,W2,29); step_B(W4,W1,30); step_B(W3,W4,31); step_B(W2,W3,32);
+ step_B(W1,W2,25); step_B(W4,W1,26); step_B(W3,W4,27); step_B(W2,W3,28);
+ step_B(W1,W2,29); step_B(W4,W1,30); step_B(W3,W4,31); step_B(W2,W3,32);
- store_le(out, W4, W3, W2, W1);
+ store_le(out, W4, W3, W2, W1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Skipjack Decryption
*/
-void Skipjack::dec(const byte in[], byte out[]) const
+void Skipjack::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u16bit W1 = load_le<u16bit>(in, 3);
- u16bit W2 = load_le<u16bit>(in, 2);
- u16bit W3 = load_le<u16bit>(in, 1);
- u16bit W4 = load_le<u16bit>(in, 0);
+ for(u32bit i = 0; i != blocks; ++i)
+ {
+ u16bit W1 = load_le<u16bit>(in, 3);
+ u16bit W2 = load_le<u16bit>(in, 2);
+ u16bit W3 = load_le<u16bit>(in, 1);
+ u16bit W4 = load_le<u16bit>(in, 0);
+
+ step_Bi(W2,W3,32); step_Bi(W3,W4,31); step_Bi(W4,W1,30); step_Bi(W1,W2,29);
+ step_Bi(W2,W3,28); step_Bi(W3,W4,27); step_Bi(W4,W1,26); step_Bi(W1,W2,25);
- step_Bi(W2,W3,32); step_Bi(W3,W4,31); step_Bi(W4,W1,30); step_Bi(W1,W2,29);
- step_Bi(W2,W3,28); step_Bi(W3,W4,27); step_Bi(W4,W1,26); step_Bi(W1,W2,25);
+ step_Ai(W1,W2,24); step_Ai(W2,W3,23); step_Ai(W3,W4,22); step_Ai(W4,W1,21);
+ step_Ai(W1,W2,20); step_Ai(W2,W3,19); step_Ai(W3,W4,18); step_Ai(W4,W1,17);
- step_Ai(W1,W2,24); step_Ai(W2,W3,23); step_Ai(W3,W4,22); step_Ai(W4,W1,21);
- step_Ai(W1,W2,20); step_Ai(W2,W3,19); step_Ai(W3,W4,18); step_Ai(W4,W1,17);
+ step_Bi(W2,W3,16); step_Bi(W3,W4,15); step_Bi(W4,W1,14); step_Bi(W1,W2,13);
+ step_Bi(W2,W3,12); step_Bi(W3,W4,11); step_Bi(W4,W1,10); step_Bi(W1,W2, 9);
- step_Bi(W2,W3,16); step_Bi(W3,W4,15); step_Bi(W4,W1,14); step_Bi(W1,W2,13);
- step_Bi(W2,W3,12); step_Bi(W3,W4,11); step_Bi(W4,W1,10); step_Bi(W1,W2, 9);
+ step_Ai(W1,W2, 8); step_Ai(W2,W3, 7); step_Ai(W3,W4, 6); step_Ai(W4,W1, 5);
+ step_Ai(W1,W2, 4); step_Ai(W2,W3, 3); step_Ai(W3,W4, 2); step_Ai(W4,W1, 1);
- step_Ai(W1,W2, 8); step_Ai(W2,W3, 7); step_Ai(W3,W4, 6); step_Ai(W4,W1, 5);
- step_Ai(W1,W2, 4); step_Ai(W2,W3, 3); step_Ai(W3,W4, 2); step_Ai(W4,W1, 1);
+ store_le(out, W4, W3, W2, W1);
- store_le(out, W4, W3, W2, W1);
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/skipjack/skipjack.h b/src/block/skipjack/skipjack.h
index 231cd9c87..f12032f36 100644
--- a/src/block/skipjack/skipjack.h
+++ b/src/block/skipjack/skipjack.h
@@ -18,18 +18,21 @@ namespace Botan {
class BOTAN_DLL Skipjack : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Skipjack"; }
BlockCipher* clone() const { return new Skipjack; }
+
Skipjack() : BlockCipher(8, 10) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
void step_A(u16bit&, u16bit&, u32bit) const;
void step_B(u16bit&, u16bit&, u32bit) const;
void step_Ai(u16bit&, u16bit&, u32bit) const;
void step_Bi(u16bit&, u16bit&, u32bit) const;
+
SecureBuffer<byte, 256> FTABLE[10];
};
diff --git a/src/block/square/square.cpp b/src/block/square/square.cpp
index cb226542d..fdd47d3b2 100644
--- a/src/block/square/square.cpp
+++ b/src/block/square/square.cpp
@@ -14,103 +14,123 @@ namespace Botan {
/*
* Square Encryption
*/
-void Square::enc(const byte in[], byte out[]) const
+void Square::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit T0, T1, T2, T3, B0, B1, B2, B3;
- B0 = TE0[in[ 0] ^ ME[ 0]] ^ TE1[in[ 4] ^ ME[ 4]] ^
- TE2[in[ 8] ^ ME[ 8]] ^ TE3[in[12] ^ ME[12]] ^ EK[0];
- B1 = TE0[in[ 1] ^ ME[ 1]] ^ TE1[in[ 5] ^ ME[ 5]] ^
- TE2[in[ 9] ^ ME[ 9]] ^ TE3[in[13] ^ ME[13]] ^ EK[1];
- B2 = TE0[in[ 2] ^ ME[ 2]] ^ TE1[in[ 6] ^ ME[ 6]] ^
- TE2[in[10] ^ ME[10]] ^ TE3[in[14] ^ ME[14]] ^ EK[2];
- B3 = TE0[in[ 3] ^ ME[ 3]] ^ TE1[in[ 7] ^ ME[ 7]] ^
- TE2[in[11] ^ ME[11]] ^ TE3[in[15] ^ ME[15]] ^ EK[3];
- for(u32bit j = 1; j != 7; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(0, B1)] ^
- TE2[get_byte(0, B2)] ^ TE3[get_byte(0, B3)] ^ EK[4*j+0];
- T1 = TE0[get_byte(1, B0)] ^ TE1[get_byte(1, B1)] ^
- TE2[get_byte(1, B2)] ^ TE3[get_byte(1, B3)] ^ EK[4*j+1];
- T2 = TE0[get_byte(2, B0)] ^ TE1[get_byte(2, B1)] ^
- TE2[get_byte(2, B2)] ^ TE3[get_byte(2, B3)] ^ EK[4*j+2];
- T3 = TE0[get_byte(3, B0)] ^ TE1[get_byte(3, B1)] ^
- TE2[get_byte(3, B2)] ^ TE3[get_byte(3, B3)] ^ EK[4*j+3];
- B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(0, T1)] ^
- TE2[get_byte(0, T2)] ^ TE3[get_byte(0, T3)] ^ EK[4*j+4];
- B1 = TE0[get_byte(1, T0)] ^ TE1[get_byte(1, T1)] ^
- TE2[get_byte(1, T2)] ^ TE3[get_byte(1, T3)] ^ EK[4*j+5];
- B2 = TE0[get_byte(2, T0)] ^ TE1[get_byte(2, T1)] ^
- TE2[get_byte(2, T2)] ^ TE3[get_byte(2, T3)] ^ EK[4*j+6];
- B3 = TE0[get_byte(3, T0)] ^ TE1[get_byte(3, T1)] ^
- TE2[get_byte(3, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4*j+7];
+ u32bit T0, T1, T2, T3, B0, B1, B2, B3;
+
+ B0 = TE0[in[ 0] ^ ME[ 0]] ^ TE1[in[ 4] ^ ME[ 4]] ^
+ TE2[in[ 8] ^ ME[ 8]] ^ TE3[in[12] ^ ME[12]] ^ EK[0];
+ B1 = TE0[in[ 1] ^ ME[ 1]] ^ TE1[in[ 5] ^ ME[ 5]] ^
+ TE2[in[ 9] ^ ME[ 9]] ^ TE3[in[13] ^ ME[13]] ^ EK[1];
+ B2 = TE0[in[ 2] ^ ME[ 2]] ^ TE1[in[ 6] ^ ME[ 6]] ^
+ TE2[in[10] ^ ME[10]] ^ TE3[in[14] ^ ME[14]] ^ EK[2];
+ B3 = TE0[in[ 3] ^ ME[ 3]] ^ TE1[in[ 7] ^ ME[ 7]] ^
+ TE2[in[11] ^ ME[11]] ^ TE3[in[15] ^ ME[15]] ^ EK[3];
+
+ for(u32bit j = 1; j != 7; j += 2)
+ {
+ T0 = TE0[get_byte(0, B0)] ^ TE1[get_byte(0, B1)] ^
+ TE2[get_byte(0, B2)] ^ TE3[get_byte(0, B3)] ^ EK[4*j+0];
+ T1 = TE0[get_byte(1, B0)] ^ TE1[get_byte(1, B1)] ^
+ TE2[get_byte(1, B2)] ^ TE3[get_byte(1, B3)] ^ EK[4*j+1];
+ T2 = TE0[get_byte(2, B0)] ^ TE1[get_byte(2, B1)] ^
+ TE2[get_byte(2, B2)] ^ TE3[get_byte(2, B3)] ^ EK[4*j+2];
+ T3 = TE0[get_byte(3, B0)] ^ TE1[get_byte(3, B1)] ^
+ TE2[get_byte(3, B2)] ^ TE3[get_byte(3, B3)] ^ EK[4*j+3];
+
+ B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(0, T1)] ^
+ TE2[get_byte(0, T2)] ^ TE3[get_byte(0, T3)] ^ EK[4*j+4];
+ B1 = TE0[get_byte(1, T0)] ^ TE1[get_byte(1, T1)] ^
+ TE2[get_byte(1, T2)] ^ TE3[get_byte(1, T3)] ^ EK[4*j+5];
+ B2 = TE0[get_byte(2, T0)] ^ TE1[get_byte(2, T1)] ^
+ TE2[get_byte(2, T2)] ^ TE3[get_byte(2, T3)] ^ EK[4*j+6];
+ B3 = TE0[get_byte(3, T0)] ^ TE1[get_byte(3, T1)] ^
+ TE2[get_byte(3, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4*j+7];
+ }
+
+ out[ 0] = SE[get_byte(0, B0)] ^ ME[16];
+ out[ 1] = SE[get_byte(0, B1)] ^ ME[17];
+ out[ 2] = SE[get_byte(0, B2)] ^ ME[18];
+ out[ 3] = SE[get_byte(0, B3)] ^ ME[19];
+ out[ 4] = SE[get_byte(1, B0)] ^ ME[20];
+ out[ 5] = SE[get_byte(1, B1)] ^ ME[21];
+ out[ 6] = SE[get_byte(1, B2)] ^ ME[22];
+ out[ 7] = SE[get_byte(1, B3)] ^ ME[23];
+ out[ 8] = SE[get_byte(2, B0)] ^ ME[24];
+ out[ 9] = SE[get_byte(2, B1)] ^ ME[25];
+ out[10] = SE[get_byte(2, B2)] ^ ME[26];
+ out[11] = SE[get_byte(2, B3)] ^ ME[27];
+ out[12] = SE[get_byte(3, B0)] ^ ME[28];
+ out[13] = SE[get_byte(3, B1)] ^ ME[29];
+ out[14] = SE[get_byte(3, B2)] ^ ME[30];
+ out[15] = SE[get_byte(3, B3)] ^ ME[31];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
- out[ 0] = SE[get_byte(0, B0)] ^ ME[16];
- out[ 1] = SE[get_byte(0, B1)] ^ ME[17];
- out[ 2] = SE[get_byte(0, B2)] ^ ME[18];
- out[ 3] = SE[get_byte(0, B3)] ^ ME[19];
- out[ 4] = SE[get_byte(1, B0)] ^ ME[20];
- out[ 5] = SE[get_byte(1, B1)] ^ ME[21];
- out[ 6] = SE[get_byte(1, B2)] ^ ME[22];
- out[ 7] = SE[get_byte(1, B3)] ^ ME[23];
- out[ 8] = SE[get_byte(2, B0)] ^ ME[24];
- out[ 9] = SE[get_byte(2, B1)] ^ ME[25];
- out[10] = SE[get_byte(2, B2)] ^ ME[26];
- out[11] = SE[get_byte(2, B3)] ^ ME[27];
- out[12] = SE[get_byte(3, B0)] ^ ME[28];
- out[13] = SE[get_byte(3, B1)] ^ ME[29];
- out[14] = SE[get_byte(3, B2)] ^ ME[30];
- out[15] = SE[get_byte(3, B3)] ^ ME[31];
}
/*
* Square Decryption
*/
-void Square::dec(const byte in[], byte out[]) const
+void Square::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit T0, T1, T2, T3, B0, B1, B2, B3;
- B0 = TD0[in[ 0] ^ MD[ 0]] ^ TD1[in[ 4] ^ MD[ 4]] ^
- TD2[in[ 8] ^ MD[ 8]] ^ TD3[in[12] ^ MD[12]] ^ DK[0];
- B1 = TD0[in[ 1] ^ MD[ 1]] ^ TD1[in[ 5] ^ MD[ 5]] ^
- TD2[in[ 9] ^ MD[ 9]] ^ TD3[in[13] ^ MD[13]] ^ DK[1];
- B2 = TD0[in[ 2] ^ MD[ 2]] ^ TD1[in[ 6] ^ MD[ 6]] ^
- TD2[in[10] ^ MD[10]] ^ TD3[in[14] ^ MD[14]] ^ DK[2];
- B3 = TD0[in[ 3] ^ MD[ 3]] ^ TD1[in[ 7] ^ MD[ 7]] ^
- TD2[in[11] ^ MD[11]] ^ TD3[in[15] ^ MD[15]] ^ DK[3];
- for(u32bit j = 1; j != 7; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(0, B1)] ^
- TD2[get_byte(0, B2)] ^ TD3[get_byte(0, B3)] ^ DK[4*j+0];
- T1 = TD0[get_byte(1, B0)] ^ TD1[get_byte(1, B1)] ^
- TD2[get_byte(1, B2)] ^ TD3[get_byte(1, B3)] ^ DK[4*j+1];
- T2 = TD0[get_byte(2, B0)] ^ TD1[get_byte(2, B1)] ^
- TD2[get_byte(2, B2)] ^ TD3[get_byte(2, B3)] ^ DK[4*j+2];
- T3 = TD0[get_byte(3, B0)] ^ TD1[get_byte(3, B1)] ^
- TD2[get_byte(3, B2)] ^ TD3[get_byte(3, B3)] ^ DK[4*j+3];
- B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(0, T1)] ^
- TD2[get_byte(0, T2)] ^ TD3[get_byte(0, T3)] ^ DK[4*j+4];
- B1 = TD0[get_byte(1, T0)] ^ TD1[get_byte(1, T1)] ^
- TD2[get_byte(1, T2)] ^ TD3[get_byte(1, T3)] ^ DK[4*j+5];
- B2 = TD0[get_byte(2, T0)] ^ TD1[get_byte(2, T1)] ^
- TD2[get_byte(2, T2)] ^ TD3[get_byte(2, T3)] ^ DK[4*j+6];
- B3 = TD0[get_byte(3, T0)] ^ TD1[get_byte(3, T1)] ^
- TD2[get_byte(3, T2)] ^ TD3[get_byte(3, T3)] ^ DK[4*j+7];
+ u32bit T0, T1, T2, T3, B0, B1, B2, B3;
+
+ B0 = TD0[in[ 0] ^ MD[ 0]] ^ TD1[in[ 4] ^ MD[ 4]] ^
+ TD2[in[ 8] ^ MD[ 8]] ^ TD3[in[12] ^ MD[12]] ^ DK[0];
+ B1 = TD0[in[ 1] ^ MD[ 1]] ^ TD1[in[ 5] ^ MD[ 5]] ^
+ TD2[in[ 9] ^ MD[ 9]] ^ TD3[in[13] ^ MD[13]] ^ DK[1];
+ B2 = TD0[in[ 2] ^ MD[ 2]] ^ TD1[in[ 6] ^ MD[ 6]] ^
+ TD2[in[10] ^ MD[10]] ^ TD3[in[14] ^ MD[14]] ^ DK[2];
+ B3 = TD0[in[ 3] ^ MD[ 3]] ^ TD1[in[ 7] ^ MD[ 7]] ^
+ TD2[in[11] ^ MD[11]] ^ TD3[in[15] ^ MD[15]] ^ DK[3];
+
+ for(u32bit j = 1; j != 7; j += 2)
+ {
+ T0 = TD0[get_byte(0, B0)] ^ TD1[get_byte(0, B1)] ^
+ TD2[get_byte(0, B2)] ^ TD3[get_byte(0, B3)] ^ DK[4*j+0];
+ T1 = TD0[get_byte(1, B0)] ^ TD1[get_byte(1, B1)] ^
+ TD2[get_byte(1, B2)] ^ TD3[get_byte(1, B3)] ^ DK[4*j+1];
+ T2 = TD0[get_byte(2, B0)] ^ TD1[get_byte(2, B1)] ^
+ TD2[get_byte(2, B2)] ^ TD3[get_byte(2, B3)] ^ DK[4*j+2];
+ T3 = TD0[get_byte(3, B0)] ^ TD1[get_byte(3, B1)] ^
+ TD2[get_byte(3, B2)] ^ TD3[get_byte(3, B3)] ^ DK[4*j+3];
+
+ B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(0, T1)] ^
+ TD2[get_byte(0, T2)] ^ TD3[get_byte(0, T3)] ^ DK[4*j+4];
+ B1 = TD0[get_byte(1, T0)] ^ TD1[get_byte(1, T1)] ^
+ TD2[get_byte(1, T2)] ^ TD3[get_byte(1, T3)] ^ DK[4*j+5];
+ B2 = TD0[get_byte(2, T0)] ^ TD1[get_byte(2, T1)] ^
+ TD2[get_byte(2, T2)] ^ TD3[get_byte(2, T3)] ^ DK[4*j+6];
+ B3 = TD0[get_byte(3, T0)] ^ TD1[get_byte(3, T1)] ^
+ TD2[get_byte(3, T2)] ^ TD3[get_byte(3, T3)] ^ DK[4*j+7];
+ }
+
+ out[ 0] = SD[get_byte(0, B0)] ^ MD[16];
+ out[ 1] = SD[get_byte(0, B1)] ^ MD[17];
+ out[ 2] = SD[get_byte(0, B2)] ^ MD[18];
+ out[ 3] = SD[get_byte(0, B3)] ^ MD[19];
+ out[ 4] = SD[get_byte(1, B0)] ^ MD[20];
+ out[ 5] = SD[get_byte(1, B1)] ^ MD[21];
+ out[ 6] = SD[get_byte(1, B2)] ^ MD[22];
+ out[ 7] = SD[get_byte(1, B3)] ^ MD[23];
+ out[ 8] = SD[get_byte(2, B0)] ^ MD[24];
+ out[ 9] = SD[get_byte(2, B1)] ^ MD[25];
+ out[10] = SD[get_byte(2, B2)] ^ MD[26];
+ out[11] = SD[get_byte(2, B3)] ^ MD[27];
+ out[12] = SD[get_byte(3, B0)] ^ MD[28];
+ out[13] = SD[get_byte(3, B1)] ^ MD[29];
+ out[14] = SD[get_byte(3, B2)] ^ MD[30];
+ out[15] = SD[get_byte(3, B3)] ^ MD[31];
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
}
- out[ 0] = SD[get_byte(0, B0)] ^ MD[16];
- out[ 1] = SD[get_byte(0, B1)] ^ MD[17];
- out[ 2] = SD[get_byte(0, B2)] ^ MD[18];
- out[ 3] = SD[get_byte(0, B3)] ^ MD[19];
- out[ 4] = SD[get_byte(1, B0)] ^ MD[20];
- out[ 5] = SD[get_byte(1, B1)] ^ MD[21];
- out[ 6] = SD[get_byte(1, B2)] ^ MD[22];
- out[ 7] = SD[get_byte(1, B3)] ^ MD[23];
- out[ 8] = SD[get_byte(2, B0)] ^ MD[24];
- out[ 9] = SD[get_byte(2, B1)] ^ MD[25];
- out[10] = SD[get_byte(2, B2)] ^ MD[26];
- out[11] = SD[get_byte(2, B3)] ^ MD[27];
- out[12] = SD[get_byte(3, B0)] ^ MD[28];
- out[13] = SD[get_byte(3, B1)] ^ MD[29];
- out[14] = SD[get_byte(3, B2)] ^ MD[30];
- out[15] = SD[get_byte(3, B3)] ^ MD[31];
}
/*
diff --git a/src/block/square/square.h b/src/block/square/square.h
index 94a1fc370..5d9cfc78c 100644
--- a/src/block/square/square.h
+++ b/src/block/square/square.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Square : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Square"; }
BlockCipher* clone() const { return new Square; }
+
Square() : BlockCipher(16, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static void transform(u32bit[4]);
diff --git a/src/block/tea/tea.cpp b/src/block/tea/tea.cpp
index 2b4212d9c..de30858da 100644
--- a/src/block/tea/tea.cpp
+++ b/src/block/tea/tea.cpp
@@ -13,37 +13,49 @@ namespace Botan {
/*
* TEA Encryption
*/
-void TEA::enc(const byte in[], byte out[]) const
+void TEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- u32bit S = 0;
- for(u32bit j = 0; j != 32; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- S += 0x9E3779B9;
- L += ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]);
- R += ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]);
- }
+ u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+
+ u32bit S = 0;
+ for(u32bit j = 0; j != 32; ++j)
+ {
+ S += 0x9E3779B9;
+ L += ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]);
+ R += ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]);
+ }
- store_be(out, L, R);
+ store_be(out, L, R);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* TEA Decryption
*/
-void TEA::dec(const byte in[], byte out[]) const
+void TEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- u32bit S = 0xC6EF3720;
- for(u32bit j = 0; j != 32; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R -= ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]);
- L -= ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]);
- S -= 0x9E3779B9;
- }
+ u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+
+ u32bit S = 0xC6EF3720;
+ for(u32bit j = 0; j != 32; ++j)
+ {
+ R -= ((L << 4) + K[2]) ^ (L + S) ^ ((L >> 5) + K[3]);
+ L -= ((R << 4) + K[0]) ^ (R + S) ^ ((R >> 5) + K[1]);
+ S -= 0x9E3779B9;
+ }
- store_be(out, L, R);
+ store_be(out, L, R);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/tea/tea.h b/src/block/tea/tea.h
index 8ddf3e330..825a051aa 100644
--- a/src/block/tea/tea.h
+++ b/src/block/tea/tea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL TEA : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { K.clear(); }
std::string name() const { return "TEA"; }
BlockCipher* clone() const { return new TEA; }
+
TEA() : BlockCipher(8, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 4> K;
};
diff --git a/src/block/twofish/twofish.cpp b/src/block/twofish/twofish.cpp
index 9784b00a2..6a482a8f3 100644
--- a/src/block/twofish/twofish.cpp
+++ b/src/block/twofish/twofish.cpp
@@ -14,91 +14,103 @@ namespace Botan {
/*
* Twofish Encryption
*/
-void Twofish::enc(const byte in[], byte out[]) const
+void Twofish::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0) ^ round_key[0];
- u32bit B = load_le<u32bit>(in, 1) ^ round_key[1];
- u32bit C = load_le<u32bit>(in, 2) ^ round_key[2];
- u32bit D = load_le<u32bit>(in, 3) ^ round_key[3];
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- u32bit X, Y;
-
- X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^
- SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)];
- Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^
- SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)];
- X += Y;
- Y += X + round_key[2*j + 9];
- X += round_key[2*j + 8];
-
- C = rotate_right(C ^ X, 1);
- D = rotate_left(D, 1) ^ Y;
-
- X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^
- SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)];
- Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^
- SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)];
- X += Y;
- Y += X + round_key[2*j + 11];
- X += round_key[2*j + 10];
-
- A = rotate_right(A ^ X, 1);
- B = rotate_left(B, 1) ^ Y;
- }
+ u32bit A = load_le<u32bit>(in, 0) ^ round_key[0];
+ u32bit B = load_le<u32bit>(in, 1) ^ round_key[1];
+ u32bit C = load_le<u32bit>(in, 2) ^ round_key[2];
+ u32bit D = load_le<u32bit>(in, 3) ^ round_key[3];
- C ^= round_key[4];
- D ^= round_key[5];
- A ^= round_key[6];
- B ^= round_key[7];
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit X, Y;
+
+ X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^
+ SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)];
+ Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^
+ SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)];
+ X += Y;
+ Y += X + round_key[2*j + 9];
+ X += round_key[2*j + 8];
+
+ C = rotate_right(C ^ X, 1);
+ D = rotate_left(D, 1) ^ Y;
+
+ X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^
+ SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)];
+ Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^
+ SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)];
+ X += Y;
+ Y += X + round_key[2*j + 11];
+ X += round_key[2*j + 10];
+
+ A = rotate_right(A ^ X, 1);
+ B = rotate_left(B, 1) ^ Y;
+ }
- store_le(out, C, D, A, B);
+ C ^= round_key[4];
+ D ^= round_key[5];
+ A ^= round_key[6];
+ B ^= round_key[7];
+
+ store_le(out, C, D, A, B);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* Twofish Decryption
*/
-void Twofish::dec(const byte in[], byte out[]) const
+void Twofish::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit A = load_le<u32bit>(in, 0) ^ round_key[4];
- u32bit B = load_le<u32bit>(in, 1) ^ round_key[5];
- u32bit C = load_le<u32bit>(in, 2) ^ round_key[6];
- u32bit D = load_le<u32bit>(in, 3) ^ round_key[7];
-
- for(u32bit j = 0; j != 16; j += 2)
+ for(u32bit i = 0; i != blocks; ++i)
{
- u32bit X, Y;
-
- X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^
- SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)];
- Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^
- SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)];
- X += Y;
- Y += X + round_key[39 - 2*j];
- X += round_key[38 - 2*j];
-
- C = rotate_left(C, 1) ^ X;
- D = rotate_right(D ^ Y, 1);
-
- X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^
- SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)];
- Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^
- SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)];
- X += Y;
- Y += X + round_key[37 - 2*j];
- X += round_key[36 - 2*j];
-
- A = rotate_left(A, 1) ^ X;
- B = rotate_right(B ^ Y, 1);
- }
+ u32bit A = load_le<u32bit>(in, 0) ^ round_key[4];
+ u32bit B = load_le<u32bit>(in, 1) ^ round_key[5];
+ u32bit C = load_le<u32bit>(in, 2) ^ round_key[6];
+ u32bit D = load_le<u32bit>(in, 3) ^ round_key[7];
- C ^= round_key[0];
- D ^= round_key[1];
- A ^= round_key[2];
- B ^= round_key[3];
+ for(u32bit j = 0; j != 16; j += 2)
+ {
+ u32bit X, Y;
+
+ X = SBox0[get_byte(3, A)] ^ SBox1[get_byte(2, A)] ^
+ SBox2[get_byte(1, A)] ^ SBox3[get_byte(0, A)];
+ Y = SBox0[get_byte(0, B)] ^ SBox1[get_byte(3, B)] ^
+ SBox2[get_byte(2, B)] ^ SBox3[get_byte(1, B)];
+ X += Y;
+ Y += X + round_key[39 - 2*j];
+ X += round_key[38 - 2*j];
+
+ C = rotate_left(C, 1) ^ X;
+ D = rotate_right(D ^ Y, 1);
+
+ X = SBox0[get_byte(3, C)] ^ SBox1[get_byte(2, C)] ^
+ SBox2[get_byte(1, C)] ^ SBox3[get_byte(0, C)];
+ Y = SBox0[get_byte(0, D)] ^ SBox1[get_byte(3, D)] ^
+ SBox2[get_byte(2, D)] ^ SBox3[get_byte(1, D)];
+ X += Y;
+ Y += X + round_key[37 - 2*j];
+ X += round_key[36 - 2*j];
+
+ A = rotate_left(A, 1) ^ X;
+ B = rotate_right(B ^ Y, 1);
+ }
- store_le(out, C, D, A, B);
+ C ^= round_key[0];
+ D ^= round_key[1];
+ A ^= round_key[2];
+ B ^= round_key[3];
+
+ store_le(out, C, D, A, B);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/twofish/twofish.h b/src/block/twofish/twofish.h
index 0640e32f8..87b9aa626 100644
--- a/src/block/twofish/twofish.h
+++ b/src/block/twofish/twofish.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL Twofish : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw();
std::string name() const { return "Twofish"; }
BlockCipher* clone() const { return new Twofish; }
+
Twofish() : BlockCipher(16, 16, 32, 8) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
static void rs_mul(byte[4], byte, u32bit);
diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp
index 5047f6594..77543e1e8 100644
--- a/src/block/xtea/xtea.cpp
+++ b/src/block/xtea/xtea.cpp
@@ -7,40 +7,51 @@
#include <botan/xtea.h>
#include <botan/loadstor.h>
-#include <botan/parsing.h>
namespace Botan {
/*
* XTEA Encryption
*/
-void XTEA::enc(const byte in[], byte out[]) const
+void XTEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- for(u32bit j = 0; j != 32; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j];
- R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1];
- }
+ u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+
+ for(u32bit j = 0; j != 32; ++j)
+ {
+ L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*j];
+ R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*j+1];
+ }
- store_be(out, L, R);
+ store_be(out, L, R);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
* XTEA Decryption
*/
-void XTEA::dec(const byte in[], byte out[]) const
+void XTEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
-
- for(u32bit j = 0; j != 32; ++j)
+ for(u32bit i = 0; i != blocks; ++i)
{
- R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j];
- L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j];
- }
+ u32bit L = load_be<u32bit>(in, 0), R = load_be<u32bit>(in, 1);
+
+ for(u32bit j = 0; j != 32; ++j)
+ {
+ R -= (((L << 4) ^ (L >> 5)) + L) ^ EK[63 - 2*j];
+ L -= (((R << 4) ^ (R >> 5)) + R) ^ EK[62 - 2*j];
+ }
- store_be(out, L, R);
+ store_be(out, L, R);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
}
/*
diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h
index d9c6066cb..de265818d 100644
--- a/src/block/xtea/xtea.h
+++ b/src/block/xtea/xtea.h
@@ -18,13 +18,15 @@ namespace Botan {
class BOTAN_DLL XTEA : public BlockCipher
{
public:
+ void encrypt_n(const byte in[], byte out[], u32bit blocks) const;
+ void decrypt_n(const byte in[], byte out[], u32bit blocks) const;
+
void clear() throw() { EK.clear(); }
std::string name() const { return "XTEA"; }
BlockCipher* clone() const { return new XTEA; }
+
XTEA() : BlockCipher(8, 16) {}
private:
- void enc(const byte[], byte[]) const;
- void dec(const byte[], byte[]) const;
void key_schedule(const byte[], u32bit);
SecureBuffer<u32bit, 64> EK;
};
diff --git a/src/build-data/arch/arm b/src/build-data/arch/arm
index 73cd02f05..c6be4ad46 100644
--- a/src/build-data/arch/arm
+++ b/src/build-data/arch/arm
@@ -19,4 +19,5 @@ xscale
sa110 -> strongarm110
sa1100 -> strongarm1100
strongarm1110 -> strongarm1100
+armv5tel -> xscale
</submodel_aliases>
diff --git a/src/build-data/arch/m68k b/src/build-data/arch/m68k
index 27f246abc..759a3dac1 100644
--- a/src/build-data/arch/m68k
+++ b/src/build-data/arch/m68k
@@ -2,6 +2,11 @@ realname "Motorola 680x0"
default_submodel 68020
+endian big
+
+# Except for Coldfire
+#unaligned ok
+
<aliases>
680x0
68k
diff --git a/src/build-data/arch/mips32 b/src/build-data/arch/mips32
index a07a0a145..9846c8fb2 100644
--- a/src/build-data/arch/mips32
+++ b/src/build-data/arch/mips32
@@ -4,20 +4,19 @@ default_submodel r3000
<aliases>
mips
+mipsel # For Debian
</aliases>
<submodels>
-mip32-r3000
-mip32-r6000
+r3000
+r6000
</submodels>
<submodel_aliases>
-r3k -> mips32-r3000
-r6k -> mips32-r6000
+r3k -> r3000
+r6k -> r6000
-r3000 -> mips32-r3000
-r6000 -> mips32-r6000
-
-mipsbe -> mips3000 # For RPM
-mipsle -> mips3000 # For RPM
+# These are for RPM
+mipsbe -> r3000
+mipsle -> r3000
</submodel_aliases>
diff --git a/src/build-data/arch/mips64 b/src/build-data/arch/mips64
index 228083848..dbb49d028 100644
--- a/src/build-data/arch/mips64
+++ b/src/build-data/arch/mips64
@@ -3,30 +3,20 @@ realname "MIPS64"
default_submodel r4400
<submodels>
-mips64-r4000
-mips64-r4100
-mips64-r4300
-mips64-r4400
-mips64-r4600
-mips64-r4560
-mips64-r5000
-mips64-r8000
-mips64-r10000
+r4000
+r4100
+r4300
+r4400
+r4600
+r4560
+r5000
+r8000
+r10000
</submodels>
<submodel_aliases>
-r4k -> mips64-r4000
-r5k -> mips64-r5000
-r8k -> mips64-r8000
-r10k -> mips64-r10000
-
-r4000 -> mips64-r4000
-r4100 -> mips64-r4100
-r4300 -> mips64-r4300
-r4400 -> mips64-r4400
-r4600 -> mips64-r4600
-r4560 -> mips64-r4560
-r5000 -> mips64-r5000
-r8000 -> mips64-r8000
-r10000 -> mips64-r10000
+r4k -> r4000
+r5k -> r5000
+r8k -> r8000
+r10k -> r10000
</submodel_aliases>
diff --git a/src/build-data/arch/ppc b/src/build-data/arch/ppc
index 16112f389..e2dfa6ea2 100644
--- a/src/build-data/arch/ppc
+++ b/src/build-data/arch/ppc
@@ -1,6 +1,7 @@
realname "PowerPC"
endian big
+unaligned ok
default_submodel ppc604
diff --git a/src/build-data/arch/s390 b/src/build-data/arch/s390
index 392f51397..312b262c4 100644
--- a/src/build-data/arch/s390
+++ b/src/build-data/arch/s390
@@ -2,6 +2,9 @@ realname "S/390 31-bit"
default_submodel s390
+endian big
+unaligned ok
+
<submodels>
s390
</submodels>
diff --git a/src/build-data/arch/s390x b/src/build-data/arch/s390x
index 49fb0bda7..9fe6bd615 100644
--- a/src/build-data/arch/s390x
+++ b/src/build-data/arch/s390x
@@ -2,6 +2,9 @@ realname "S/390 64-bit"
default_submodel s390x
+endian big
+unaligned ok
+
<submodels>
s390x
</submodels>
diff --git a/src/build-data/botan.doxy.in b/src/build-data/botan.doxy.in
index 2da5e1244..87d6e58eb 100644
--- a/src/build-data/botan.doxy.in
+++ b/src/build-data/botan.doxy.in
@@ -97,7 +97,7 @@ FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = YES
-STRIP_CODE_COMMENTS = YES
+STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index e4ab0f44b..bd900d412 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -22,6 +22,12 @@
#define BOTAN_KARAT_SQR_THRESHOLD 32
#define BOTAN_PRIVATE_KEY_OP_BLINDING_BITS 64
+/* Toggles for parallel block cipher mode processing */
+#define BOTAN_PARALLEL_BLOCKS_ECB 8
+#define BOTAN_PARALLEL_BLOCKS_CTR 8
+#define BOTAN_PARALLEL_BLOCKS_EAX 8
+#define BOTAN_PARALLEL_BLOCKS_XTS 8
+
/* PK key consistency checking toggles */
#define BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD 1
#define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD 1
diff --git a/src/build-data/cc/gcc b/src/build-data/cc/gcc
index bde1e5822..7ab80b6ca 100644
--- a/src/build-data/cc/gcc
+++ b/src/build-data/cc/gcc
@@ -73,7 +73,6 @@ ppc64 -> "-mcpu=SUBMODEL" ppc
# Note that the 'linking' bit means "use this for both compiling *and* linking"
<mach_abi_linking>
amd64 -> "-m64"
-mips32 -> "-mabi=n32"
mips64 -> "-mabi=64"
s390 -> "-m31"
s390x -> "-m64"
@@ -84,6 +83,7 @@ ppc64 -> "-m64"
# This should probably be used on most/all targets, but the docs are incomplete
openbsd -> "-pthread"
freebsd -> "-pthread"
+dragonfly -> "-pthread"
netbsd -> "-pthread -D_NETBSD_SOURCE"
qnx -> "-fexceptions -D_QNX_SOURCE"
</mach_abi_linking>
diff --git a/src/build-data/cc/open64 b/src/build-data/cc/open64
new file mode 100644
index 000000000..b7c1e9e99
--- /dev/null
+++ b/src/build-data/cc/open64
@@ -0,0 +1,30 @@
+realname "Open64"
+
+binary_name "openCC"
+
+compile_option "-c "
+output_to_option "-o "
+add_include_dir_option "-I"
+add_lib_dir_option "-L"
+add_lib_option "-l"
+
+lib_opt_flags "-O3 -OPT:alias=TYPED"
+check_opt_flags "-O3 -OPT:alias=TYPED"
+debug_flags "-g3"
+no_debug_flags "-fomit-frame-pointer"
+shared_flags "-fPIC"
+lang_flags "-ansi -LANG:ansi-for-init-scope=ON"
+warning_flags "-Wall -W"
+
+dll_import_flags ""
+dll_export_flags ""
+
+makefile_style unix
+
+<so_link_flags>
+default -> "$(CXX) -shared -Wl,-soname,$(SONAME)"
+</so_link_flags>
+
+<mach_abi_linking>
+amd64 -> "-m64"
+</mach_abi_linking>
diff --git a/src/build-data/os/dragonfly b/src/build-data/os/dragonfly
new file mode 100644
index 000000000..7e3663435
--- /dev/null
+++ b/src/build-data/os/dragonfly
@@ -0,0 +1,11 @@
+realname "DragonFly"
+
+os_type unix
+
+<target_features>
+posix_mlock
+</target_features>
+
+<supports_shared>
+all
+</supports_shared>
diff --git a/src/cert/cvc/cvc_cert.cpp b/src/cert/cvc/cvc_cert.cpp
index 352178fd2..5c2e28c39 100644
--- a/src/cert/cvc/cvc_cert.cpp
+++ b/src/cert/cvc/cvc_cert.cpp
@@ -58,7 +58,7 @@ void EAC1_1_CVC::force_decode()
if(cpi != 0)
throw Decoding_Error("EAC1_1 certificate´s cpi was not 0");
- // XXX: PK algos have no notion of EAC encoder/decoder currently
+ // FIXME: PK algos have no notion of EAC encoder/decoder currently
#if 0
ECDSA_PublicKey tmp_pk;
std::unique_ptr<EAC1_1_CVC_Decoder> dec = tmp_pk.cvc_eac1_1_decoder();
diff --git a/src/cert/cvc/cvc_req.cpp b/src/cert/cvc/cvc_req.cpp
index 5b2a2c4d4..aa29d8ee6 100644
--- a/src/cert/cvc/cvc_req.cpp
+++ b/src/cert/cvc/cvc_req.cpp
@@ -41,7 +41,7 @@ void EAC1_1_Req::force_decode()
throw Decoding_Error("EAC1_1 request´s cpi was not 0");
}
- // XXX: No EAC support in ECDSA
+ // FIXME: No EAC support in ECDSA
#if 0
ECDSA_PublicKey tmp_pk;
std::unique_ptr<EAC1_1_CVC_Decoder> dec = tmp_pk.cvc_eac1_1_decoder();
diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp
index 47c46ca1c..6a81c40ec 100644
--- a/src/cert/cvc/cvc_self.cpp
+++ b/src/cert/cvc/cvc_self.cpp
@@ -86,7 +86,7 @@ EAC1_1_CVC create_self_signed_cert(Private_Key const& key,
std::unique_ptr<Botan::PK_Signer> signer(get_pk_signer(*priv_key, padding_and_hash));
-#if 0
+#if 0 // FIXME
std::unique_ptr<EAC1_1_CVC_Encoder> enc(priv_key->cvc_eac1_1_encoder());
MemoryVector<byte> enc_public_key = enc->public_key(sig_algo);
#else
@@ -224,7 +224,7 @@ EAC1_1_CVC link_cvca(EAC1_1_CVC const& signer,
ECDSA_PublicKey* subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get());
subj_pk->set_parameter_encoding(ENC_EXPLICIT);
-#if 0
+#if 0 // FIXME
std::unique_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder());
MemoryVector<byte> enc_public_key = enc->public_key(sig_algo);
#else
diff --git a/src/codec/openpgp/openpgp.cpp b/src/codec/openpgp/openpgp.cpp
index 7f9cf5f9c..bfba828af 100644
--- a/src/codec/openpgp/openpgp.cpp
+++ b/src/codec/openpgp/openpgp.cpp
@@ -7,6 +7,7 @@
#include <botan/openpgp.h>
#include <botan/filters.h>
+#include <botan/basefilt.h>
#include <botan/charset.h>
#include <botan/crc24.h>
diff --git a/src/cryptobox/cryptobox.cpp b/src/cryptobox/cryptobox.cpp
new file mode 100644
index 000000000..c27bbaffa
--- /dev/null
+++ b/src/cryptobox/cryptobox.cpp
@@ -0,0 +1,146 @@
+/*
+* Cryptobox Message Routines
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/cryptobox.h>
+#include <botan/filters.h>
+#include <botan/pipe.h>
+#include <botan/serpent.h>
+#include <botan/sha2_64.h>
+#include <botan/ctr.h>
+#include <botan/hmac.h>
+#include <botan/pbkdf2.h>
+#include <botan/pem.h>
+#include <botan/loadstor.h>
+#include <botan/mem_ops.h>
+
+namespace Botan {
+
+namespace CryptoBox {
+
+namespace {
+
+/*
+First 24 bits of SHA-256("Botan Cryptobox"), followed by 8 0 bits
+for later use as flags, etc if needed
+*/
+const u32bit CRYPTOBOX_VERSION_CODE = 0xEFC22400;
+
+const u32bit VERSION_CODE_LEN = 4;
+const u32bit CIPHER_KEY_LEN = 32;
+const u32bit CIPHER_IV_LEN = 16;
+const u32bit MAC_KEY_LEN = 32;
+const u32bit MAC_OUTPUT_LEN = 20;
+const u32bit PBKDF_SALT_LEN = 10;
+const u32bit PBKDF_ITERATIONS = 8 * 1024;
+
+const u32bit PBKDF_OUTPUT_LEN = CIPHER_KEY_LEN + CIPHER_IV_LEN + MAC_KEY_LEN;
+
+}
+
+std::string encrypt(const byte input[], u32bit input_len,
+ const std::string& passphrase,
+ RandomNumberGenerator& rng)
+ {
+ SecureVector<byte> pbkdf_salt(PBKDF_SALT_LEN);
+ rng.randomize(pbkdf_salt.begin(), pbkdf_salt.size());
+
+ PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512));
+ pbkdf.change_salt(pbkdf_salt.begin(), pbkdf_salt.size());
+ pbkdf.set_iterations(PBKDF_ITERATIONS);
+
+ OctetString mk = pbkdf.derive_key(PBKDF_OUTPUT_LEN, passphrase);
+
+ SymmetricKey cipher_key(mk.begin(), CIPHER_KEY_LEN);
+ SymmetricKey mac_key(mk.begin() + CIPHER_KEY_LEN, MAC_KEY_LEN);
+ InitializationVector iv(mk.begin() + CIPHER_KEY_LEN + MAC_KEY_LEN,
+ CIPHER_IV_LEN);
+
+ Pipe pipe(new CTR_BE(new Serpent, cipher_key, iv),
+ new Fork(
+ 0,
+ new MAC_Filter(new HMAC(new SHA_512),
+ mac_key, MAC_OUTPUT_LEN)));
+
+ pipe.process_msg(input, input_len);
+
+ /*
+ Output format is:
+ version # (4 bytes)
+ salt (10 bytes)
+ mac (20 bytes)
+ ciphertext
+ */
+ u32bit ciphertext_len = pipe.remaining(0);
+
+ SecureVector<byte> out_buf;
+
+ for(u32bit i = 0; i != VERSION_CODE_LEN; ++i)
+ out_buf.append(get_byte(i, CRYPTOBOX_VERSION_CODE));
+
+ out_buf.append(pbkdf_salt.begin(), pbkdf_salt.size());
+
+ out_buf.grow_to(out_buf.size() + MAC_OUTPUT_LEN + ciphertext_len);
+ pipe.read(out_buf + VERSION_CODE_LEN + PBKDF_SALT_LEN, MAC_OUTPUT_LEN, 1);
+ pipe.read(out_buf + VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN,
+ ciphertext_len, 0);
+
+ return PEM_Code::encode(out_buf.begin(), out_buf.size(),
+ "BOTAN CRYPTOBOX MESSAGE");
+ }
+
+std::string decrypt(const byte input[], u32bit input_len,
+ const std::string& passphrase)
+ {
+ DataSource_Memory input_src(input, input_len);
+ SecureVector<byte> ciphertext =
+ PEM_Code::decode_check_label(input_src,
+ "BOTAN CRYPTOBOX MESSAGE");
+
+ if(ciphertext.size() < (VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN))
+ throw Decoding_Error("Invalid CryptoBox input");
+
+ for(u32bit i = 0; i != VERSION_CODE_LEN; ++i)
+ if(ciphertext[i] != get_byte(i, CRYPTOBOX_VERSION_CODE))
+ throw Decoding_Error("Bad CryptoBox version");
+
+ SecureVector<byte> pbkdf_salt(ciphertext + VERSION_CODE_LEN, PBKDF_SALT_LEN);
+
+ PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512));
+ pbkdf.change_salt(pbkdf_salt.begin(), pbkdf_salt.size());
+ pbkdf.set_iterations(PBKDF_ITERATIONS);
+
+ OctetString mk = pbkdf.derive_key(PBKDF_OUTPUT_LEN, passphrase);
+
+ SymmetricKey cipher_key(mk.begin(), CIPHER_KEY_LEN);
+ SymmetricKey mac_key(mk.begin() + CIPHER_KEY_LEN, MAC_KEY_LEN);
+ InitializationVector iv(mk.begin() + CIPHER_KEY_LEN + MAC_KEY_LEN,
+ CIPHER_IV_LEN);
+
+ Pipe pipe(new Fork(
+ new CTR_BE(new Serpent, cipher_key, iv),
+ new MAC_Filter(new HMAC(new SHA_512),
+ mac_key, MAC_OUTPUT_LEN)));
+
+ const u32bit ciphertext_offset =
+ VERSION_CODE_LEN + PBKDF_SALT_LEN + MAC_OUTPUT_LEN;
+
+ pipe.process_msg(ciphertext + ciphertext_offset,
+ ciphertext.size() - ciphertext_offset);
+
+ byte computed_mac[MAC_OUTPUT_LEN];
+ pipe.read(computed_mac, MAC_OUTPUT_LEN, 1);
+
+ if(!same_mem(computed_mac, ciphertext + VERSION_CODE_LEN + PBKDF_SALT_LEN,
+ MAC_OUTPUT_LEN))
+ throw Integrity_Failure("CryptoBox integrity failure");
+
+ return pipe.read_all_as_string(0);
+ }
+
+}
+
+}
diff --git a/src/cryptobox/cryptobox.h b/src/cryptobox/cryptobox.h
new file mode 100644
index 000000000..a30cb244a
--- /dev/null
+++ b/src/cryptobox/cryptobox.h
@@ -0,0 +1,42 @@
+/*
+* Cryptobox Message Routines
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_CRYPTOBOX_H__
+#define BOTAN_CRYPTOBOX_H__
+
+#include <string>
+#include <botan/rng.h>
+
+namespace Botan {
+
+namespace CryptoBox {
+
+/**
+* Encrypt a message
+* @param input the input data
+* @param input_len the length of input in bytes
+* @param passphrase the passphrase used to encrypt the message
+* @param rng a ref to a random number generator, such as AutoSeeded_RNG
+*/
+BOTAN_DLL std::string encrypt(const byte input[], u32bit input_len,
+ const std::string& passphrase,
+ RandomNumberGenerator& rng);
+
+/**
+* Decrypt a message encrypted with CryptoBox::encrypt
+* @param input the input data
+* @param input_len the length of input in bytes
+* @param passphrase the passphrase used to encrypt the message
+*/
+BOTAN_DLL std::string decrypt(const byte input[], u32bit input_len,
+ const std::string& passphrase);
+
+}
+
+}
+
+#endif
diff --git a/src/cryptobox/info.txt b/src/cryptobox/info.txt
new file mode 100644
index 000000000..b9b98060f
--- /dev/null
+++ b/src/cryptobox/info.txt
@@ -0,0 +1,22 @@
+realname "Crypto Box"
+
+load_on auto
+
+define CRYPTO_BOX
+
+<add>
+cryptobox.h
+cryptobox.cpp
+</add>
+
+<requires>
+filters
+ctr
+hmac
+rng
+serpent
+sha2
+base64
+pbkdf2
+pem
+</requires>
diff --git a/src/engine/openssl/ossl_md.cpp b/src/engine/openssl/ossl_md.cpp
index 08672cfc8..7c8fb678c 100644
--- a/src/engine/openssl/ossl_md.cpp
+++ b/src/engine/openssl/ossl_md.cpp
@@ -95,20 +95,30 @@ EVP_HashFunction::~EVP_HashFunction()
HashFunction* OpenSSL_Engine::find_hash(const SCAN_Name& request,
Algorithm_Factory&) const
{
+#ifndef OPENSSL_NO_SHA
if(request.algo_name() == "SHA-160")
return new EVP_HashFunction(EVP_sha1(), "SHA-160");
+#endif
+#ifndef OPENSSL_NO_MD2
if(request.algo_name() == "MD2")
return new EVP_HashFunction(EVP_md2(), "MD2");
+#endif
+#ifndef OPENSSL_NO_MD4
if(request.algo_name() == "MD4")
return new EVP_HashFunction(EVP_md4(), "MD4");
+#endif
+#ifndef OPENSSL_NO_MD5
if(request.algo_name() == "MD5")
return new EVP_HashFunction(EVP_md5(), "MD5");
+#endif
+#ifndef OPENSSL_NO_RIPEMD
if(request.algo_name() == "RIPEMD-160")
return new EVP_HashFunction(EVP_ripemd160(), "RIPEMD-160");
+#endif
return 0;
}
diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp
index c738b3d96..9f68a070e 100644
--- a/src/engine/sse2_eng/eng_sse2.cpp
+++ b/src/engine/sse2_eng/eng_sse2.cpp
@@ -1,6 +1,6 @@
/**
* SSE2 Assembly Engine
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -11,10 +11,27 @@
#include <botan/sha1_sse2.h>
#endif
+#if defined(BOTAN_HAS_SERPENT_SSE2)
+ #include <botan/serp_sse2.h>
+#endif
+
namespace Botan {
-HashFunction* SSE2_Assembler_Engine::find_hash(const SCAN_Name& request,
- Algorithm_Factory&) const
+BlockCipher*
+SSE2_Assembler_Engine::find_block_cipher(const SCAN_Name& request,
+ Algorithm_Factory&) const
+ {
+#if defined(BOTAN_HAS_SERPENT_SSE2)
+ if(request.algo_name() == "Serpent")
+ return new Serpent_SSE2;
+#endif
+
+ return 0;
+ }
+
+HashFunction*
+SSE2_Assembler_Engine::find_hash(const SCAN_Name& request,
+ Algorithm_Factory&) const
{
#if defined(BOTAN_HAS_SHA1_SSE2)
if(request.algo_name() == "SHA-160")
diff --git a/src/engine/sse2_eng/eng_sse2.h b/src/engine/sse2_eng/eng_sse2.h
index 129697e8f..c6b0ce889 100644
--- a/src/engine/sse2_eng/eng_sse2.h
+++ b/src/engine/sse2_eng/eng_sse2.h
@@ -1,6 +1,6 @@
/**
* SSE2 Assembly Engine
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -17,6 +17,9 @@ class BOTAN_DLL SSE2_Assembler_Engine : public Engine
public:
std::string provider_name() const { return "sse2"; }
private:
+ BlockCipher* find_block_cipher(const SCAN_Name&,
+ Algorithm_Factory&) const;
+
HashFunction* find_hash(const SCAN_Name& reqeust,
Algorithm_Factory&) const;
};
diff --git a/src/engine/sse2_eng/info.txt b/src/engine/sse2_eng/info.txt
index 6242c7fee..7595b8eb5 100644
--- a/src/engine/sse2_eng/info.txt
+++ b/src/engine/sse2_eng/info.txt
@@ -10,6 +10,13 @@ eng_sse2.h
</add>
<arch>
-ia32
+pentium-m
+pentium4
+prescott
amd64
</arch>
+
+<cc>
+gcc
+icc
+</cc>
diff --git a/src/entropy/dev_random/info.txt b/src/entropy/dev_random/info.txt
index 6622886af..fddb7ac06 100644
--- a/src/entropy/dev_random/info.txt
+++ b/src/entropy/dev_random/info.txt
@@ -16,6 +16,7 @@ beos
cygwin
darwin
freebsd
+dragonfly
hpux
irix
linux
diff --git a/src/entropy/egd/es_egd.cpp b/src/entropy/egd/es_egd.cpp
index a2e3d3791..9e37f8f17 100644
--- a/src/entropy/egd/es_egd.cpp
+++ b/src/entropy/egd/es_egd.cpp
@@ -98,7 +98,7 @@ u32bit EGD_EntropySource::EGD_Socket::read(byte outbuf[], u32bit length)
return static_cast<u32bit>(count);
}
- catch(std::exception& e)
+ catch(std::exception)
{
this->close();
// Will attempt to reopen next poll
diff --git a/src/entropy/egd/info.txt b/src/entropy/egd/info.txt
index 6b34f395c..85ba86c00 100644
--- a/src/entropy/egd/info.txt
+++ b/src/entropy/egd/info.txt
@@ -20,6 +20,7 @@ aix
cygwin
darwin
freebsd
+dragonfly
hpux
irix
linux
diff --git a/src/entropy/proc_walk/es_ftw.cpp b/src/entropy/proc_walk/es_ftw.cpp
index fe9dfec38..2016f099a 100644
--- a/src/entropy/proc_walk/es_ftw.cpp
+++ b/src/entropy/proc_walk/es_ftw.cpp
@@ -81,7 +81,7 @@ int Directory_Walker::next_fd()
if(S_ISDIR(stat_buf.st_mode))
add_directory(full_path);
- else if(S_ISREG(stat_buf.st_mode))
+ else if(S_ISREG(stat_buf.st_mode) && (stat_buf.st_mode & S_IROTH))
{
int fd = ::open(full_path.c_str(), O_RDONLY | O_NOCTTY);
@@ -118,7 +118,7 @@ void FTW_EntropySource::poll(Entropy_Accumulator& accum)
if(!dir)
dir = new Directory_Walker(path);
- MemoryRegion<byte>& io_buffer = accum.get_io_buffer(2048);
+ MemoryRegion<byte>& io_buffer = accum.get_io_buffer(128);
for(u32bit i = 0; i != MAX_FILES_READ_PER_POLL; ++i)
{
diff --git a/src/entropy/proc_walk/info.txt b/src/entropy/proc_walk/info.txt
index 9f4836458..db96ccdb8 100644
--- a/src/entropy/proc_walk/info.txt
+++ b/src/entropy/proc_walk/info.txt
@@ -15,6 +15,7 @@ aix
cygwin
darwin
freebsd
+dragonfly
hpux
irix
linux
diff --git a/src/filters/algo_filt.cpp b/src/filters/algo_filt.cpp
index 23f7a20cf..3268276a6 100644
--- a/src/filters/algo_filt.cpp
+++ b/src/filters/algo_filt.cpp
@@ -18,7 +18,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) :
buffer(DEFAULT_BUFFERSIZE)
{
Algorithm_Factory& af = global_state().algorithm_factory();
- base_ptr = cipher = af.make_stream_cipher(sc_name);
+ cipher = af.make_stream_cipher(sc_name);
}
/*
@@ -27,7 +27,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name) :
StreamCipher_Filter::StreamCipher_Filter(StreamCipher* stream_cipher) :
buffer(DEFAULT_BUFFERSIZE)
{
- base_ptr = cipher = stream_cipher;
+ cipher = stream_cipher;
}
/*
@@ -38,7 +38,7 @@ StreamCipher_Filter::StreamCipher_Filter(const std::string& sc_name,
buffer(DEFAULT_BUFFERSIZE)
{
Algorithm_Factory& af = global_state().algorithm_factory();
- base_ptr = cipher = af.make_stream_cipher(sc_name);
+ cipher = af.make_stream_cipher(sc_name);
cipher->set_key(key);
}
@@ -95,7 +95,7 @@ MAC_Filter::MAC_Filter(const std::string& mac_name, u32bit len) :
OUTPUT_LENGTH(len)
{
Algorithm_Factory& af = global_state().algorithm_factory();
- base_ptr = mac = af.make_mac(mac_name);
+ mac = af.make_mac(mac_name);
}
/*
@@ -105,7 +105,7 @@ MAC_Filter::MAC_Filter(const std::string& mac_name, const SymmetricKey& key,
u32bit len) : OUTPUT_LENGTH(len)
{
Algorithm_Factory& af = global_state().algorithm_factory();
- base_ptr = mac = af.make_mac(mac_name);
+ mac = af.make_mac(mac_name);
mac->set_key(key);
}
diff --git a/src/filters/basefilt.cpp b/src/filters/basefilt.cpp
index 02dbd8a73..c91a5aa62 100644
--- a/src/filters/basefilt.cpp
+++ b/src/filters/basefilt.cpp
@@ -50,25 +50,4 @@ Fork::Fork(Filter* filters[], u32bit count)
set_next(filters, count);
}
-/*
-* Set the algorithm key
-*/
-void Keyed_Filter::set_key(const SymmetricKey& key)
- {
- if(base_ptr)
- base_ptr->set_key(key);
- else
- throw Invalid_State("Keyed_Filter::set_key: No base algorithm set");
- }
-
-/*
-* Check if a keylength is valid
-*/
-bool Keyed_Filter::valid_keylength(u32bit n) const
- {
- if(base_ptr)
- return base_ptr->valid_keylength(n);
- throw Invalid_State("Keyed_Filter::valid_keylength: No base algorithm set");
- }
-
}
diff --git a/src/filters/basefilt.h b/src/filters/basefilt.h
index 75625abb0..348ad6fd3 100644
--- a/src/filters/basefilt.h
+++ b/src/filters/basefilt.h
@@ -9,7 +9,6 @@
#define BOTAN_BASEFILT_H__
#include <botan/filter.h>
-#include <botan/sym_algo.h>
namespace Botan {
@@ -62,38 +61,6 @@ class BOTAN_DLL Fork : public Fanout_Filter
Fork(Filter* filter_arr[], u32bit length);
};
-/**
-* This class represents keyed filters, i.e. filters that have to be
-* fed with a key in order to function.
-*/
-class BOTAN_DLL Keyed_Filter : public Filter
- {
- public:
-
- /**
- * Set the key of this filter.
- * @param key the key to set
- */
- virtual void set_key(const SymmetricKey& key);
-
- /**
- * Set the initialization vector of this filter.
- * @param iv the initialization vector to set
- */
- virtual void set_iv(const InitializationVector&) {}
-
- /**
- * Check whether a key length is valid for this filter.
- * @param length the key length to be checked for validity
- * @return true if the key length is valid, false otherwise
- */
- virtual bool valid_keylength(u32bit length) const;
-
- Keyed_Filter() { base_ptr = 0; }
- protected:
- SymmetricAlgorithm* base_ptr;
- };
-
}
#endif
diff --git a/src/filters/fd_unix/info.txt b/src/filters/fd_unix/info.txt
index e1f30ea28..d87978cb0 100644
--- a/src/filters/fd_unix/info.txt
+++ b/src/filters/fd_unix/info.txt
@@ -16,6 +16,7 @@ beos
cygwin
darwin
freebsd
+dragonfly
hpux
irix
linux
diff --git a/src/filters/filters.h b/src/filters/filters.h
index 725651f7d..964be0bd8 100644
--- a/src/filters/filters.h
+++ b/src/filters/filters.h
@@ -15,7 +15,9 @@
#include <botan/pipe.h>
#include <botan/basefilt.h>
+#include <botan/key_filt.h>
#include <botan/data_snk.h>
+
#include <botan/scan_name.h>
#if defined(BOTAN_HAS_BASE64_CODEC)
@@ -36,6 +38,13 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter
public:
/**
+ * Write input data
+ * @param input data
+ * @param input_len length of input in bytes
+ */
+ void write(const byte input[], u32bit input_len);
+
+ /**
* Seek in the stream.
* @param position the position to seek ahead
*/
@@ -53,7 +62,20 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter
* @param iv the initialization vector to set
*/
void set_iv(const InitializationVector& iv);
- void write(const byte[], u32bit);
+
+ /**
+ * Set the key of this filter.
+ * @param key the key to set
+ */
+ void set_key(const SymmetricKey& key) { cipher->set_key(key); }
+
+ /**
+ * Check whether a key length is valid for this filter.
+ * @param length the key length to be checked for validity
+ * @return true if the key length is valid, false otherwise
+ */
+ bool valid_keylength(u32bit length) const
+ { return cipher->valid_keylength(length); }
/**
* Construct a stream cipher filter.
@@ -126,6 +148,20 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter
void end_msg();
/**
+ * Set the key of this filter.
+ * @param key the key to set
+ */
+ void set_key(const SymmetricKey& key) { mac->set_key(key); }
+
+ /**
+ * Check whether a key length is valid for this filter.
+ * @param length the key length to be checked for validity
+ * @return true if the key length is valid, false otherwise
+ */
+ bool valid_keylength(u32bit length) const
+ { return mac->valid_keylength(length); }
+
+ /**
* Construct a MAC filter. The MAC key will be left empty.
* @param mac the MAC to use
* @param len the output length of this filter. Leave the default
@@ -136,7 +172,7 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter
MAC_Filter(MessageAuthenticationCode* mac_obj,
u32bit out_len = 0) : OUTPUT_LENGTH(out_len)
{
- base_ptr = mac = mac_obj;
+ mac = mac_obj;
}
/**
@@ -152,7 +188,7 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter
const SymmetricKey& key,
u32bit out_len = 0) : OUTPUT_LENGTH(out_len)
{
- base_ptr = mac = mac_obj;
+ mac = mac_obj;
mac->set_key(key);
}
diff --git a/src/filters/info.txt b/src/filters/info.txt
index 79a92a9c5..fb8108659 100644
--- a/src/filters/info.txt
+++ b/src/filters/info.txt
@@ -17,6 +17,7 @@ data_src.h
filter.cpp
filter.h
filters.h
+key_filt.h
out_buf.cpp
out_buf.h
pbe.h
diff --git a/src/filters/key_filt.h b/src/filters/key_filt.h
new file mode 100644
index 000000000..36af91f88
--- /dev/null
+++ b/src/filters/key_filt.h
@@ -0,0 +1,45 @@
+/*
+* Keyed_Filter
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_KEYED_FILTER_H__
+#define BOTAN_KEYED_FILTER_H__
+
+#include <botan/filter.h>
+#include <botan/sym_algo.h>
+
+namespace Botan {
+
+/**
+* This class represents keyed filters, i.e. filters that have to be
+* fed with a key in order to function.
+*/
+class BOTAN_DLL Keyed_Filter : public Filter
+ {
+ public:
+ /**
+ * Set the key of this filter.
+ * @param key the key to set
+ */
+ virtual void set_key(const SymmetricKey& key) = 0;
+
+ /**
+ * Set the initialization vector of this filter.
+ * @param iv the initialization vector to set
+ */
+ virtual void set_iv(const InitializationVector&) {}
+
+ /**
+ * Check whether a key length is valid for this filter.
+ * @param length the key length to be checked for validity
+ * @return true if the key length is valid, false otherwise
+ */
+ virtual bool valid_keylength(u32bit length) const = 0;
+ };
+
+}
+
+#endif
diff --git a/src/hash/md4_ia32/info.txt b/src/hash/md4_ia32/info.txt
index e5287dc5d..fee7dd1a8 100644
--- a/src/hash/md4_ia32/info.txt
+++ b/src/hash/md4_ia32/info.txt
@@ -23,6 +23,7 @@ icc
<os>
linux
freebsd
+dragonfly
netbsd
openbsd
solaris
diff --git a/src/hash/md4_ia32/md4_ia32_imp.S b/src/hash/md4_ia32/md4_ia32_imp.S
index 9b728c73d..ca04cbe4e 100644
--- a/src/hash/md4_ia32/md4_ia32_imp.S
+++ b/src/hash/md4_ia32/md4_ia32_imp.S
@@ -1,7 +1,9 @@
-/*************************************************
-* MD4 Source File *
-* (C) 1999-2007 Jack Lloyd *
-*************************************************/
+/*
+* MD4 Source File
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
#include <botan/asm_macr.h>
diff --git a/src/hash/md5_ia32/info.txt b/src/hash/md5_ia32/info.txt
index f69ab82e6..ad9923b26 100644
--- a/src/hash/md5_ia32/info.txt
+++ b/src/hash/md5_ia32/info.txt
@@ -23,6 +23,7 @@ icc
<os>
linux
freebsd
+dragonfly
netbsd
openbsd
solaris
diff --git a/src/hash/md5_ia32/md5_ia32_imp.S b/src/hash/md5_ia32/md5_ia32_imp.S
index 7f9268a1e..8087bbdbc 100644
--- a/src/hash/md5_ia32/md5_ia32_imp.S
+++ b/src/hash/md5_ia32/md5_ia32_imp.S
@@ -1,7 +1,9 @@
-/*************************************************
-* MD5 Source File *
-* (C) 1999-2007 Jack Lloyd *
-*************************************************/
+/*
+* MD5 Source File
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
#include <botan/asm_macr.h>
diff --git a/src/hash/sha1_amd64/sha1_amd64_imp.S b/src/hash/sha1_amd64/sha1_amd64_imp.S
index f20494999..34a8318ed 100644
--- a/src/hash/sha1_amd64/sha1_amd64_imp.S
+++ b/src/hash/sha1_amd64/sha1_amd64_imp.S
@@ -1,7 +1,9 @@
-/*************************************************
-* SHA-160 Source File *
-* (C) 1999-2007 Jack Lloyd *
-*************************************************/
+/*
+* SHA-160 Source File
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
#include <botan/asm_macr.h>
diff --git a/src/hash/sha1_ia32/info.txt b/src/hash/sha1_ia32/info.txt
index ca14028b8..bfb321145 100644
--- a/src/hash/sha1_ia32/info.txt
+++ b/src/hash/sha1_ia32/info.txt
@@ -23,6 +23,7 @@ icc
<os>
linux
freebsd
+dragonfly
netbsd
openbsd
solaris
diff --git a/src/hash/sha1_ia32/sha1_ia32_imp.S b/src/hash/sha1_ia32/sha1_ia32_imp.S
index b7f881383..e76b9fb76 100644
--- a/src/hash/sha1_ia32/sha1_ia32_imp.S
+++ b/src/hash/sha1_ia32/sha1_ia32_imp.S
@@ -1,7 +1,9 @@
-/*************************************************
-* SHA-160 Source File *
-* (C) 1999-2007 Jack Lloyd *
-*************************************************/
+/*
+* SHA-160 Source File
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
#include <botan/asm_macr.h>
diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt
index b8d693b70..995c2513e 100644
--- a/src/hash/sha1_sse2/info.txt
+++ b/src/hash/sha1_sse2/info.txt
@@ -10,18 +10,6 @@ sha1_sse2.cpp
sha1_sse2.h
</add>
-<arch>
-pentium-m
-pentium4
-prescott
-amd64
-</arch>
-
-<cc>
-gcc
-icc
-</cc>
-
<requires>
sha1
sse2_eng
diff --git a/src/libstate/info.txt b/src/libstate/info.txt
index 7ca35c5a4..6eaa2f70b 100644
--- a/src/libstate/info.txt
+++ b/src/libstate/info.txt
@@ -1,6 +1,6 @@
realname "Botan Libstate Module"
-load_on auto
+load_on always
define LIBSTATE_MODULE
diff --git a/src/libstate/pk_engine.h b/src/libstate/pk_engine.h
index 3f8650a4e..256a47c20 100644
--- a/src/libstate/pk_engine.h
+++ b/src/libstate/pk_engine.h
@@ -9,6 +9,7 @@
#define BOTAN_ENGINE_PK_LOOKUP_H__
#include <botan/bigint.h>
+#include <botan/pow_mod.h>
#if defined(BOTAN_HAS_IF_PUBLIC_KEY_FAMILY)
#include <botan/if_op.h>
diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp
index 4ca6e6d59..889ef7367 100644
--- a/src/libstate/scan_name.cpp
+++ b/src/libstate/scan_name.cpp
@@ -1,6 +1,6 @@
/**
-SCAN Name Abstraction
-(C) 2008 Jack Lloyd
+* SCAN Name Abstraction
+* (C) 2008 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
diff --git a/src/libstate/scan_name.h b/src/libstate/scan_name.h
index 9e7af40d6..b3f2004e2 100644
--- a/src/libstate/scan_name.h
+++ b/src/libstate/scan_name.h
@@ -1,6 +1,6 @@
/**
-SCAN Name Abstraction
-(C) 2008 Jack Lloyd
+* SCAN Name Abstraction
+* (C) 2008 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
diff --git a/src/mac/mac.cpp b/src/mac/mac.cpp
index 96df25503..04b259647 100644
--- a/src/mac/mac.cpp
+++ b/src/mac/mac.cpp
@@ -1,6 +1,6 @@
/**
-Message Authentication Code base class
-(C) 1999-2008 Jack Lloyd
+* Message Authentication Code base class
+* (C) 1999-2008 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
diff --git a/src/math/bigint/monty_amd64/info.txt b/src/math/bigint/monty_amd64/info.txt
index 7fb70da46..a897045b2 100644
--- a/src/math/bigint/monty_amd64/info.txt
+++ b/src/math/bigint/monty_amd64/info.txt
@@ -21,6 +21,7 @@ icc
<os>
linux
freebsd
+dragonfly
netbsd
openbsd
solaris
diff --git a/src/math/bigint/monty_amd64/mp_monty.S b/src/math/bigint/monty_amd64/mp_monty.S
index 3dd4040bc..22045c369 100644
--- a/src/math/bigint/monty_amd64/mp_monty.S
+++ b/src/math/bigint/monty_amd64/mp_monty.S
@@ -1,7 +1,9 @@
-/*************************************************
-* Montgomery Reduction Source File *
-* (C) 2008 Jack Lloyd *
-*************************************************/
+/*
+* Montgomery Reduction Source File
+* (C) 2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
#include <botan/asm_macr.h>
diff --git a/src/math/bigint/mp_asm64/mp_asm.h b/src/math/bigint/mp_asm64/mp_asm.h
index d1583e236..c9159eaa7 100644
--- a/src/math/bigint/mp_asm64/mp_asm.h
+++ b/src/math/bigint/mp_asm64/mp_asm.h
@@ -57,7 +57,7 @@ namespace Botan {
// with 64-bit registers/ALU, but no 64x64->128 multiply.
inline void bigint_2word_mul(word a, word b, word* z1, word* z0)
{
- const u32bit MP_HWORD_BITS = MP_WORD_BITS / 2;
+ const u32bit MP_HWORD_BITS = BOTAN_MP_WORD_BITS / 2;
const word MP_HWORD_MASK = ((word)1 << MP_HWORD_BITS) - 1;
const word a_hi = (a >> MP_HWORD_BITS);
diff --git a/src/math/bigint/mulop_amd64/info.txt b/src/math/bigint/mulop_amd64/info.txt
index c4b14db93..77990df80 100644
--- a/src/math/bigint/mulop_amd64/info.txt
+++ b/src/math/bigint/mulop_amd64/info.txt
@@ -21,6 +21,7 @@ icc
<os>
linux
freebsd
+dragonfly
netbsd
openbsd
solaris
diff --git a/src/math/bigint/mulop_amd64/mp_mulop_amd64.S b/src/math/bigint/mulop_amd64/mp_mulop_amd64.S
index e5bba23fb..63ac55e95 100644
--- a/src/math/bigint/mulop_amd64/mp_mulop_amd64.S
+++ b/src/math/bigint/mulop_amd64/mp_mulop_amd64.S
@@ -1,7 +1,9 @@
-/*************************************************
-* Simple O(N^2) Multiplication and Squaring *
-* (C) 1999-2008 Jack Lloyd *
-*************************************************/
+/*
+* Simple O(N^2) Multiplication and Squaring
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
#include <botan/asm_macr.h>
diff --git a/src/math/bigint/mulop_ia32/info.txt b/src/math/bigint/mulop_ia32/info.txt
index a7b525bfb..b995dd8d7 100644
--- a/src/math/bigint/mulop_ia32/info.txt
+++ b/src/math/bigint/mulop_ia32/info.txt
@@ -23,6 +23,7 @@ icc
<os>
linux
freebsd
+dragonfly
netbsd
openbsd
solaris
diff --git a/src/math/bigint/mulop_ia32/mp_mulop.S b/src/math/bigint/mulop_ia32/mp_mulop.S
index a5f0d3b27..716166fd9 100644
--- a/src/math/bigint/mulop_ia32/mp_mulop.S
+++ b/src/math/bigint/mulop_ia32/mp_mulop.S
@@ -1,7 +1,9 @@
-/*************************************************
-* Multiply/Add Algorithm Source File *
-* (C) 1999-2007 Jack Lloyd *
-*************************************************/
+/*
+* Multiply/Add Algorithm Source File
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
#include <botan/asm_macr.h>
diff --git a/src/modes/ctr/ctr.cpp b/src/modes/ctr/ctr.cpp
index 9eb42ec5a..d458d7848 100644
--- a/src/modes/ctr/ctr.cpp
+++ b/src/modes/ctr/ctr.cpp
@@ -1,6 +1,6 @@
/*
* CTR Mode
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -11,12 +11,21 @@
namespace Botan {
+namespace {
+
+const u32bit PARALLEL_BLOCKS = BOTAN_PARALLEL_BLOCKS_CTR;
+
+}
+
/*
* CTR-BE Constructor
*/
-CTR_BE::CTR_BE(BlockCipher* ciph) :
- BlockCipherMode(ciph, "CTR-BE", ciph->BLOCK_SIZE, 1)
+CTR_BE::CTR_BE(BlockCipher* ciph) : cipher(ciph)
{
+ position = 0;
+
+ counter.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS);
+ enc_buffer.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS);
}
/*
@@ -24,39 +33,88 @@ CTR_BE::CTR_BE(BlockCipher* ciph) :
*/
CTR_BE::CTR_BE(BlockCipher* ciph, const SymmetricKey& key,
const InitializationVector& iv) :
- BlockCipherMode(ciph, "CTR-BE", ciph->BLOCK_SIZE, 1)
+ cipher(ciph)
{
- set_key(key);
+ position = 0;
+
+ counter.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS);
+ enc_buffer.create(ciph->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ cipher->set_key(key);
set_iv(iv);
}
/*
+* CTR_BE Destructor
+*/
+CTR_BE::~CTR_BE()
+ {
+ delete cipher;
+ }
+
+/*
+* Return the name of this type
+*/
+std::string CTR_BE::name() const
+ {
+ return ("CTR-BE/" + cipher->name());
+ }
+
+/*
+* Set CTR-BE IV
+*/
+void CTR_BE::set_iv(const InitializationVector& iv)
+ {
+ const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
+
+ if(iv.length() != BLOCK_SIZE)
+ throw Invalid_IV_Length(name(), iv.length());
+
+ enc_buffer.clear();
+ position = 0;
+
+ counter.copy(0, iv.begin(), iv.length());
+
+ for(u32bit i = 1; i != PARALLEL_BLOCKS; ++i)
+ {
+ counter.copy(i*BLOCK_SIZE,
+ counter.begin() + (i-1)*BLOCK_SIZE, BLOCK_SIZE);
+
+ for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j)
+ if(++counter[i*BLOCK_SIZE+j])
+ break;
+ }
+
+ cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS);
+ }
+
+/*
* CTR-BE Encryption/Decryption
*/
void CTR_BE::write(const byte input[], u32bit length)
{
- u32bit copied = std::min(BLOCK_SIZE - position, length);
- xor_buf(buffer + position, input, copied);
- send(buffer + position, copied);
+ u32bit copied = std::min(enc_buffer.size() - position, length);
+ xor_buf(enc_buffer + position, input, copied);
+ send(enc_buffer + position, copied);
input += copied;
length -= copied;
position += copied;
- if(position == BLOCK_SIZE)
+ if(position == enc_buffer.size())
increment_counter();
- while(length >= BLOCK_SIZE)
+ while(length >= enc_buffer.size())
{
- xor_buf(buffer, input, BLOCK_SIZE);
- send(buffer, BLOCK_SIZE);
+ xor_buf(enc_buffer, input, enc_buffer.size());
+ send(enc_buffer, enc_buffer.size());
- input += BLOCK_SIZE;
- length -= BLOCK_SIZE;
+ input += enc_buffer.size();
+ length -= enc_buffer.size();
increment_counter();
}
- xor_buf(buffer + position, input, length);
- send(buffer + position, length);
+ xor_buf(enc_buffer + position, input, length);
+ send(enc_buffer + position, length);
position += length;
}
@@ -65,10 +123,23 @@ void CTR_BE::write(const byte input[], u32bit length)
*/
void CTR_BE::increment_counter()
{
- for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j)
- if(++state[j])
- break;
- cipher->encrypt(state, buffer);
+ for(u32bit i = 0; i != PARALLEL_BLOCKS; ++i)
+ {
+ byte* this_ctr = counter + i*cipher->BLOCK_SIZE;
+
+ byte last_byte = this_ctr[cipher->BLOCK_SIZE-1];
+ last_byte += PARALLEL_BLOCKS;
+
+ if(this_ctr[cipher->BLOCK_SIZE-1] > last_byte)
+ for(s32bit j = cipher->BLOCK_SIZE - 2; j >= 0; --j)
+ if(++this_ctr[j])
+ break;
+
+ this_ctr[cipher->BLOCK_SIZE-1] = last_byte;
+ }
+
+ cipher->encrypt_n(counter, enc_buffer, PARALLEL_BLOCKS);
+
position = 0;
}
diff --git a/src/modes/ctr/ctr.h b/src/modes/ctr/ctr.h
index aa0db5761..1948ffe48 100644
--- a/src/modes/ctr/ctr.h
+++ b/src/modes/ctr/ctr.h
@@ -8,22 +8,37 @@
#ifndef BOTAN_COUNTER_MODE_H__
#define BOTAN_COUNTER_MODE_H__
-#include <botan/modebase.h>
-#include <botan/modebase.h>
+#include <botan/key_filt.h>
+#include <botan/block_cipher.h>
namespace Botan {
/*
* CTR-BE Mode
*/
-class BOTAN_DLL CTR_BE : public BlockCipherMode
+class BOTAN_DLL CTR_BE : public Keyed_Filter
{
public:
+ std::string name() const;
+
+ void set_iv(const InitializationVector&);
+
+ void set_key(const SymmetricKey& key) { cipher->set_key(key); }
+
+ bool valid_keylength(u32bit key_len) const
+ { return cipher->valid_keylength(key_len); }
+
CTR_BE(BlockCipher*);
CTR_BE(BlockCipher*, const SymmetricKey&, const InitializationVector&);
+
+ ~CTR_BE();
private:
void write(const byte[], u32bit);
void increment_counter();
+
+ BlockCipher* cipher;
+ SecureVector<byte> counter, enc_buffer;
+ u32bit position;
};
}
diff --git a/src/modes/eax/eax.h b/src/modes/eax/eax.h
index 1bb2e510d..f569f2ede 100644
--- a/src/modes/eax/eax.h
+++ b/src/modes/eax/eax.h
@@ -8,7 +8,7 @@
#ifndef BOTAN_EAX_H__
#define BOTAN_EAX_H__
-#include <botan/basefilt.h>
+#include <botan/key_filt.h>
#include <botan/block_cipher.h>
#include <botan/mac.h>
diff --git a/src/modes/ecb/ecb.cpp b/src/modes/ecb/ecb.cpp
index 8da0a4802..988a8b3f2 100644
--- a/src/modes/ecb/ecb.cpp
+++ b/src/modes/ecb/ecb.cpp
@@ -9,22 +9,60 @@
namespace Botan {
+namespace {
+
+const u32bit PARALLEL_BLOCKS = BOTAN_PARALLEL_BLOCKS_ECB;
+
+}
+
/*
-* Verify the IV is not set
+* ECB_Encryption Constructor
*/
-bool ECB::valid_iv_size(u32bit iv_size) const
+ECB_Encryption::ECB_Encryption(BlockCipher* ciph,
+ BlockCipherModePaddingMethod* pad)
{
- if(iv_size == 0)
- return true;
- return false;
+ cipher = ciph;
+ padder = pad;
+
+ plaintext.create(cipher->BLOCK_SIZE);
+ ciphertext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ position = 0;
+ }
+
+/*
+* ECB_Encryption Constructor
+*/
+ECB_Encryption::ECB_Encryption(BlockCipher* ciph,
+ BlockCipherModePaddingMethod* pad,
+ const SymmetricKey& key)
+ {
+ cipher = ciph;
+ padder = pad;
+
+ plaintext.create(cipher->BLOCK_SIZE);
+ ciphertext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ position = 0;
+
+ cipher->set_key(key);
+ }
+
+/*
+* ECB_Encryption Destructor
+*/
+ECB_Encryption::~ECB_Encryption()
+ {
+ delete cipher;
+ delete padder;
}
/*
* Return an ECB mode name
*/
-std::string ECB::name() const
+std::string ECB_Encryption::name() const
{
- return (cipher->name() + "/" + mode_name + "/" + padder->name());
+ return (cipher->name() + "/ECB/" + padder->name());
}
/*
@@ -32,23 +70,34 @@ std::string ECB::name() const
*/
void ECB_Encryption::write(const byte input[], u32bit length)
{
- buffer.copy(position, input, length);
- if(position + length >= BLOCK_SIZE)
+ const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
+
+ if(position)
{
- cipher->encrypt(buffer);
- send(buffer, BLOCK_SIZE);
- input += (BLOCK_SIZE - position);
- length -= (BLOCK_SIZE - position);
- while(length >= BLOCK_SIZE)
+ plaintext.copy(position, input, length);
+
+ if(position + length >= BLOCK_SIZE)
{
- cipher->encrypt(input, buffer);
- send(buffer, BLOCK_SIZE);
- input += BLOCK_SIZE;
- length -= BLOCK_SIZE;
+ cipher->encrypt(plaintext, ciphertext);
+ send(ciphertext, BLOCK_SIZE);
+ input += (BLOCK_SIZE - position);
+ length -= (BLOCK_SIZE - position);
+ position = 0;
}
- buffer.copy(input, length);
- position = 0;
}
+
+ while(length >= BLOCK_SIZE)
+ {
+ const u32bit to_proc =
+ std::min<u32bit>(length, ciphertext.size()) / BLOCK_SIZE;
+
+ cipher->encrypt_n(input, ciphertext, to_proc);
+ send(ciphertext, to_proc * BLOCK_SIZE);
+ input += to_proc * BLOCK_SIZE;
+ length -= to_proc * BLOCK_SIZE;
+ }
+
+ plaintext.copy(position, input, length);
position += length;
}
@@ -57,6 +106,8 @@ void ECB_Encryption::write(const byte input[], u32bit length)
*/
void ECB_Encryption::end_msg()
{
+ const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
+
SecureVector<byte> padding(BLOCK_SIZE);
padder->pad(padding, padding.size(), position);
write(padding, padder->pad_bytes(BLOCK_SIZE, position));
@@ -65,27 +116,93 @@ void ECB_Encryption::end_msg()
}
/*
+* ECB_Decryption Constructor
+*/
+ECB_Decryption::ECB_Decryption(BlockCipher* ciph,
+ BlockCipherModePaddingMethod* pad)
+ {
+ cipher = ciph;
+ padder = pad;
+
+ ciphertext.create(cipher->BLOCK_SIZE);
+ plaintext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ position = 0;
+ }
+
+/*
+* ECB_Decryption Constructor
+*/
+ECB_Decryption::ECB_Decryption(BlockCipher* ciph,
+ BlockCipherModePaddingMethod* pad,
+ const SymmetricKey& key)
+ {
+ cipher = ciph;
+ padder = pad;
+
+ ciphertext.create(cipher->BLOCK_SIZE);
+ plaintext.create(cipher->BLOCK_SIZE * PARALLEL_BLOCKS);
+
+ position = 0;
+
+ cipher->set_key(key);
+ }
+
+/*
+* ECB_Decryption Destructor
+*/
+ECB_Decryption::~ECB_Decryption()
+ {
+ delete cipher;
+ delete padder;
+ }
+
+/*
+* Return an ECB mode name
+*/
+std::string ECB_Decryption::name() const
+ {
+ return (cipher->name() + "/ECB/" + padder->name());
+ }
+
+/*
* Decrypt in ECB mode
*/
void ECB_Decryption::write(const byte input[], u32bit length)
{
- buffer.copy(position, input, length);
- if(position + length > BLOCK_SIZE)
+ const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE;
+
+ if(position)
{
- cipher->decrypt(buffer);
- send(buffer, BLOCK_SIZE);
- input += (BLOCK_SIZE - position);
- length -= (BLOCK_SIZE - position);
- while(length > BLOCK_SIZE)
+ ciphertext.copy(position, input, length);
+
+ if(position + length > BLOCK_SIZE)
{
- cipher->decrypt(input, buffer);
- send(buffer, BLOCK_SIZE);
- input += BLOCK_SIZE;
- length -= BLOCK_SIZE;
+ cipher->decrypt(ciphertext, plaintext);
+ send(plaintext, BLOCK_SIZE);
+ input += (BLOCK_SIZE - position);
+ length -= (BLOCK_SIZE - position);
+ position = 0;
}
- buffer.copy(input, length);
- position = 0;
}
+
+ while(length > BLOCK_SIZE)
+ {
+ /* Always leave at least 1 byte left over, to ensure that (as long
+ as the input message actually is a multiple of the block size)
+ we will have the full final block left over in end_msg so as
+ to remove the padding
+ */
+ const u32bit to_proc =
+ std::min<u32bit>(length - 1, plaintext.size()) / BLOCK_SIZE;
+
+ cipher->decrypt_n(input, plaintext, to_proc);
+ send(plaintext, to_proc * BLOCK_SIZE);
+ input += to_proc * BLOCK_SIZE;
+ length -= to_proc * BLOCK_SIZE;
+ }
+
+ ciphertext.copy(position, input, length);
position += length;
}
@@ -94,11 +211,11 @@ void ECB_Decryption::write(const byte input[], u32bit length)
*/
void ECB_Decryption::end_msg()
{
- if(position != BLOCK_SIZE)
+ if(position != cipher->BLOCK_SIZE)
throw Decoding_Error(name());
- cipher->decrypt(buffer);
- send(buffer, padder->unpad(buffer, BLOCK_SIZE));
- state = buffer;
+
+ cipher->decrypt(ciphertext);
+ send(ciphertext, padder->unpad(ciphertext, cipher->BLOCK_SIZE));
position = 0;
}
diff --git a/src/modes/ecb/ecb.h b/src/modes/ecb/ecb.h
index 5230f9b14..ff9ea9635 100644
--- a/src/modes/ecb/ecb.h
+++ b/src/modes/ecb/ecb.h
@@ -1,6 +1,6 @@
/*
* ECB Mode
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -8,64 +8,74 @@
#ifndef BOTAN_ECB_H__
#define BOTAN_ECB_H__
-#include <botan/modebase.h>
-#include <botan/mode_pad.h>
+#include <botan/basefilt.h>
#include <botan/block_cipher.h>
+#include <botan/mode_pad.h>
-namespace Botan {
-
-/*
-* ECB
-*/
-class BOTAN_DLL ECB : public BlockCipherMode
- {
- protected:
- ECB(BlockCipher* ciph, BlockCipherModePaddingMethod* pad) :
- BlockCipherMode(ciph, "ECB", 0), padder(pad) {}
- ~ECB() { delete padder; }
+#include <botan/modebase.h>
- std::string name() const;
- BlockCipherModePaddingMethod* padder;
- private:
- bool valid_iv_size(u32bit) const;
- };
+namespace Botan {
/*
* ECB Encryption
*/
-class BOTAN_DLL ECB_Encryption : public ECB
+class BOTAN_DLL ECB_Encryption : public Keyed_Filter
{
public:
+ std::string name() const;
+
+ void set_key(const SymmetricKey& key) { cipher->set_key(key); }
+
+ bool valid_keylength(u32bit key_len) const
+ { return cipher->valid_keylength(key_len); }
+
ECB_Encryption(BlockCipher* ciph,
- BlockCipherModePaddingMethod* pad) :
- ECB(ciph, pad) {}
+ BlockCipherModePaddingMethod* pad);
ECB_Encryption(BlockCipher* ciph,
BlockCipherModePaddingMethod* pad,
- const SymmetricKey& key) :
- ECB(ciph, pad) { set_key(key); }
+ const SymmetricKey& key);
+
+ ~ECB_Encryption();
private:
void write(const byte[], u32bit);
void end_msg();
+
+ BlockCipher* cipher;
+ BlockCipherModePaddingMethod* padder;
+ SecureVector<byte> plaintext, ciphertext;
+ u32bit position;
};
/*
* ECB Decryption
*/
-class BOTAN_DLL ECB_Decryption : public ECB
+class BOTAN_DLL ECB_Decryption : public Keyed_Filter
{
public:
+ std::string name() const;
+
+ void set_key(const SymmetricKey& key) { cipher->set_key(key); }
+
+ bool valid_keylength(u32bit key_len) const
+ { return cipher->valid_keylength(key_len); }
+
ECB_Decryption(BlockCipher* ciph,
- BlockCipherModePaddingMethod* pad) :
- ECB(ciph, pad) {}
+ BlockCipherModePaddingMethod* pad);
ECB_Decryption(BlockCipher* ciph,
BlockCipherModePaddingMethod* pad,
- const SymmetricKey& key) :
- ECB(ciph, pad) { set_key(key); }
+ const SymmetricKey& key);
+
+ ~ECB_Decryption();
private:
void write(const byte[], u32bit);
void end_msg();
+
+ BlockCipher* cipher;
+ BlockCipherModePaddingMethod* padder;
+ SecureVector<byte> plaintext, ciphertext;
+ u32bit position;
};
}
diff --git a/src/modes/modebase.cpp b/src/modes/modebase.cpp
index 8293acc54..b048862a4 100644
--- a/src/modes/modebase.cpp
+++ b/src/modes/modebase.cpp
@@ -19,7 +19,7 @@ BlockCipherMode::BlockCipherMode(BlockCipher* cipher_ptr,
BLOCK_SIZE(cipher_ptr->BLOCK_SIZE), BUFFER_SIZE(buf_mult * BLOCK_SIZE),
IV_METHOD(iv_meth), mode_name(cipher_mode_name)
{
- base_ptr = cipher = cipher_ptr;
+ cipher = cipher_ptr;
buffer.create(BUFFER_SIZE);
state.create(iv_size);
position = 0;
diff --git a/src/modes/modebase.h b/src/modes/modebase.h
index 173fde58c..4a15524b6 100644
--- a/src/modes/modebase.h
+++ b/src/modes/modebase.h
@@ -8,7 +8,7 @@
#ifndef BOTAN_MODEBASE_H__
#define BOTAN_MODEBASE_H__
-#include <botan/basefilt.h>
+#include <botan/key_filt.h>
#include <botan/block_cipher.h>
namespace Botan {
@@ -21,12 +21,17 @@ class BOTAN_DLL BlockCipherMode : public Keyed_Filter
public:
std::string name() const;
+ void set_iv(const InitializationVector&);
+ void set_key(const SymmetricKey& key) { cipher->set_key(key); }
+
+ bool valid_keylength(u32bit key_len) const
+ { return cipher->valid_keylength(key_len); }
+
BlockCipherMode(BlockCipher*, const std::string&,
u32bit, u32bit = 0, u32bit = 1);
virtual ~BlockCipherMode() { delete cipher; }
protected:
- void set_iv(const InitializationVector&);
const u32bit BLOCK_SIZE, BUFFER_SIZE, IV_METHOD;
const std::string mode_name;
BlockCipher* cipher;
diff --git a/src/modes/xts/xts.cpp b/src/modes/xts/xts.cpp
index 8819c85dc..8780ae166 100644
--- a/src/modes/xts/xts.cpp
+++ b/src/modes/xts/xts.cpp
@@ -41,7 +41,6 @@ XTS_Encryption::XTS_Encryption(BlockCipher* ciph) : cipher(ciph)
throw std::invalid_argument("Bad cipher for XTS: " + cipher->name());
cipher2 = cipher->clone();
- buffer.create(cipher->BLOCK_SIZE);
tweak.create(cipher->BLOCK_SIZE);
buffer.create(2 * cipher->BLOCK_SIZE);
position = 0;
@@ -58,7 +57,6 @@ XTS_Encryption::XTS_Encryption(BlockCipher* ciph,
throw std::invalid_argument("Bad cipher for XTS: " + cipher->name());
cipher2 = cipher->clone();
- buffer.create(cipher->BLOCK_SIZE);
tweak.create(cipher->BLOCK_SIZE);
buffer.create(2 * cipher->BLOCK_SIZE);
position = 0;
@@ -188,6 +186,8 @@ void XTS_Encryption::end_msg()
send(buffer, position);
}
+
+ position = 0;
}
/*
@@ -197,7 +197,6 @@ XTS_Decryption::XTS_Decryption(BlockCipher* ciph)
{
cipher = ciph;
cipher2 = ciph->clone();
- buffer.create(cipher->BLOCK_SIZE);
tweak.create(cipher->BLOCK_SIZE);
buffer.create(2 * cipher->BLOCK_SIZE);
position = 0;
@@ -212,7 +211,6 @@ XTS_Decryption::XTS_Decryption(BlockCipher* ciph,
{
cipher = ciph;
cipher2 = ciph->clone();
- buffer.create(cipher->BLOCK_SIZE);
tweak.create(cipher->BLOCK_SIZE);
buffer.create(2 * cipher->BLOCK_SIZE);
position = 0;
@@ -339,6 +337,8 @@ void XTS_Decryption::end_msg()
send(buffer, position);
}
+
+ position = 0;
}
}
diff --git a/src/modes/xts/xts.h b/src/modes/xts/xts.h
index 01558175b..9badd3666 100644
--- a/src/modes/xts/xts.h
+++ b/src/modes/xts/xts.h
@@ -8,7 +8,7 @@
#ifndef BOTAN_XTS_H__
#define BOTAN_XTS_H__
-#include <botan/basefilt.h>
+#include <botan/key_filt.h>
#include <botan/block_cipher.h>
namespace Botan {
@@ -22,6 +22,9 @@ class BOTAN_DLL XTS_Encryption : public Keyed_Filter
void set_key(const SymmetricKey& key);
void set_iv(const InitializationVector& iv);
+ bool valid_keylength(u32bit key_len) const
+ { return cipher->valid_keylength(key_len); }
+
std::string name() const;
XTS_Encryption(BlockCipher* ciph);
@@ -52,6 +55,9 @@ class BOTAN_DLL XTS_Decryption : public Keyed_Filter
void set_key(const SymmetricKey& key);
void set_iv(const InitializationVector& iv);
+ bool valid_keylength(u32bit key_len) const
+ { return cipher->valid_keylength(key_len); }
+
std::string name() const;
XTS_Decryption(BlockCipher* ciph);
diff --git a/src/pubkey/dsa/dsa_core.cpp b/src/pubkey/dsa/dsa_core.cpp
index e144d2467..e5a23a5c3 100644
--- a/src/pubkey/dsa/dsa_core.cpp
+++ b/src/pubkey/dsa/dsa_core.cpp
@@ -13,12 +13,6 @@
namespace Botan {
-namespace {
-
-const u32bit BLINDING_BITS = BOTAN_PRIVATE_KEY_OP_BLINDING_BITS;
-
-}
-
/*
* DSA_Core Constructor
*/
diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp
index bebfc3705..6c7d02c74 100644
--- a/src/pubkey/ecc_key/ecc_key.cpp
+++ b/src/pubkey/ecc_key/ecc_key.cpp
@@ -57,7 +57,7 @@ void EC_PublicKey::X509_load_hook()
affirm_init();
mp_public_point->check_invariants();
}
- catch(Illegal_Point exc)
+ catch(Illegal_Point)
{
throw Decoding_Error("decoded public point was found not to lie on curve");
}
diff --git a/src/pubkey/eckaeg/eckaeg.cpp b/src/pubkey/eckaeg/eckaeg.cpp
index 1b315d101..5787f062d 100644
--- a/src/pubkey/eckaeg/eckaeg.cpp
+++ b/src/pubkey/eckaeg/eckaeg.cpp
@@ -129,9 +129,10 @@ MemoryVector<byte> ECKAEG_PrivateKey::public_value() const
/**
* Derive a key
*/
-SecureVector<byte> ECKAEG_PrivateKey::derive_key(const byte key[], u32bit key_len) const
+SecureVector<byte> ECKAEG_PrivateKey::derive_key(const byte key[],
+ u32bit key_len) const
{
- MemoryVector<byte> key_x(key, key_len); // XXX fix this, nasty/slow
+ MemoryVector<byte> key_x(key, key_len); // FIXME: nasty/slow
PointGFp point = OS2ECP(key_x, public_point().get_curve());
return m_eckaeg_core.agree(point);
diff --git a/src/pubkey/pk_codecs/pkcs8.h b/src/pubkey/pk_codecs/pkcs8.h
index 87f8ba326..28008bdba 100644
--- a/src/pubkey/pk_codecs/pkcs8.h
+++ b/src/pubkey/pk_codecs/pkcs8.h
@@ -30,7 +30,7 @@ class BOTAN_DLL PKCS8_Encoder
* Get the DER encoded key.
* @return the DER encoded key
*/
- // XXX: Why not SecureVector?
+ // FIXME: Why not SecureVector?
virtual MemoryVector<byte> key_bits() const = 0;
virtual ~PKCS8_Encoder() {}
};
@@ -117,11 +117,6 @@ BOTAN_DLL std::string PEM_encode(const Private_Key& key,
const std::string& pass,
const std::string& pbe_algo = "");
-BOTAN_DLL std::string PEM_encode(const Private_Key&,
- const std::string&,
- const std::string& = "");
-
-
/**
* Load a key from a data source.
* @param source the data source providing the encoded key
diff --git a/src/rng/auto_rng/auto_rng.cpp b/src/rng/auto_rng/auto_rng.cpp
index 171c83cca..07b2ddec2 100644
--- a/src/rng/auto_rng/auto_rng.cpp
+++ b/src/rng/auto_rng/auto_rng.cpp
@@ -140,7 +140,7 @@ AutoSeeded_RNG::AutoSeeded_RNG(u32bit poll_bits)
#endif
if(!rng)
- throw Algorithm_Not_Found("No usable RNG found enabled in build");
+ throw Internal_Error("No usable RNG found enabled in build");
/* If X9.31 is available, use it to wrap the other RNG as a failsafe */
#if defined(BOTAN_HAS_X931_RNG)
diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp
index ea032b04e..d644e866e 100644
--- a/src/selftest/selftest.cpp
+++ b/src/selftest/selftest.cpp
@@ -173,7 +173,7 @@ bool passes_self_tests(Algorithm_Factory& af)
"0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B")));
}
}
- catch(std::exception& e)
+ catch(std::exception)
{
return false;
}
diff --git a/src/stream/turing/turing.cpp b/src/stream/turing/turing.cpp
index b988568c3..1e2203480 100644
--- a/src/stream/turing/turing.cpp
+++ b/src/stream/turing/turing.cpp
@@ -218,25 +218,6 @@ u32bit Turing::fixedS(u32bit W)
}
/*
-* Generate the expanded Turing Sbox tables
-*/
-void Turing::gen_sbox(MemoryRegion<u32bit>& S, u32bit which,
- const MemoryRegion<u32bit>& K)
- {
- for(u32bit j = 0; j != 256; ++j)
- {
- u32bit W = 0, C = j;
-
- for(u32bit k = 0; k < K.size(); ++k)
- {
- C = SBOX[get_byte(which, K[k]) ^ C];
- W ^= rotate_left(Q_BOX[C], k + 8*which);
- }
- S[j] = (W & rotate_right(0x00FFFFFF, 8*which)) | (C << (24 - 8*which));
- }
- }
-
-/*
* Turing Key Schedule
*/
void Turing::key_schedule(const byte key[], u32bit length)
@@ -250,10 +231,31 @@ void Turing::key_schedule(const byte key[], u32bit length)
PHT(K);
- gen_sbox(S0, 0, K);
- gen_sbox(S1, 1, K);
- gen_sbox(S2, 2, K);
- gen_sbox(S3, 3, K);
+ for(u32bit i = 0; i != 256; ++i)
+ {
+ u32bit W0 = 0, C0 = i;
+ u32bit W1 = 0, C1 = i;
+ u32bit W2 = 0, C2 = i;
+ u32bit W3 = 0, C3 = i;
+
+ for(u32bit j = 0; j < K.size(); ++j)
+ {
+ C0 = SBOX[get_byte(0, K[j]) ^ C0];
+ C1 = SBOX[get_byte(1, K[j]) ^ C1];
+ C2 = SBOX[get_byte(2, K[j]) ^ C2];
+ C3 = SBOX[get_byte(3, K[j]) ^ C3];
+
+ W0 ^= rotate_left(Q_BOX[C0], j);
+ W1 ^= rotate_left(Q_BOX[C1], j + 8);
+ W2 ^= rotate_left(Q_BOX[C2], j + 16);
+ W3 ^= rotate_left(Q_BOX[C3], j + 24);
+ }
+
+ S0[i] = (W0 & 0x00FFFFFF) | (C0 << 24);
+ S1[i] = (W1 & 0xFF00FFFF) | (C1 << 16);
+ S2[i] = (W2 & 0xFFFF00FF) | (C2 << 8);
+ S3[i] = (W3 & 0xFFFFFF00) | C3;
+ }
resync(0, 0);
}
diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h
index d48c1d8a8..455d3c612 100644
--- a/src/stream/turing/turing.h
+++ b/src/stream/turing/turing.h
@@ -29,8 +29,6 @@ class BOTAN_DLL Turing : public StreamCipher
void generate();
static u32bit fixedS(u32bit);
- static void gen_sbox(MemoryRegion<u32bit>&, u32bit,
- const MemoryRegion<u32bit>&);
static const u32bit Q_BOX[256];
static const byte SBOX[256];
diff --git a/src/timer/gettimeofday/info.txt b/src/timer/gettimeofday/info.txt
index d3812eedf..a58e8088d 100644
--- a/src/timer/gettimeofday/info.txt
+++ b/src/timer/gettimeofday/info.txt
@@ -16,6 +16,7 @@ beos
cygwin
darwin
freebsd
+dragonfly
hpux
irix
linux
diff --git a/src/timer/posix_rt/info.txt b/src/timer/posix_rt/info.txt
index 7501373bb..fa530ea1a 100644
--- a/src/timer/posix_rt/info.txt
+++ b/src/timer/posix_rt/info.txt
@@ -18,6 +18,7 @@ linux -> rt
cygwin
linux
#freebsd
+dragonfly
#netbsd
#openbsd
</os>
diff --git a/src/utils/bswap.h b/src/utils/bswap.h
index af51e4e47..08095b319 100644
--- a/src/utils/bswap.h
+++ b/src/utils/bswap.h
@@ -31,9 +31,9 @@ inline u32bit reverse_bytes(u32bit input)
asm("bswapl %0" : "=r" (input) : "0" (input));
return input;
-#elif defined(_MSC_VER) && defined(BOTAN_TARGER_ARCH_IS_IA32)
+#elif defined(_MSC_VER) && defined(BOTAN_TARGET_ARCH_IS_IA32)
/* Visual C++ inline asm for 32-bit x86, by Yves Jerschow */
- __asm mov eax, x;
+ __asm mov eax, input;
__asm bswap eax;
#else
diff --git a/src/utils/info.txt b/src/utils/info.txt
index 95ea5fc2e..ab50b88ad 100644
--- a/src/utils/info.txt
+++ b/src/utils/info.txt
@@ -2,7 +2,7 @@ realname "Utility Functions"
define UTIL_FUNCTIONS
-load_on auto
+load_on always
<libs>
tru64 -> rt