aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checks/bench.cpp2
-rw-r--r--checks/check.cpp2
-rw-r--r--checks/misc.cpp2
-rw-r--r--checks/validate.dat17
-rwxr-xr-xconfigure.py80
-rw-r--r--doc/log.txt3
-rw-r--r--src/block/idea/idea.cpp78
-rw-r--r--src/block/idea/idea.h2
-rw-r--r--src/block/idea_sse2/idea_sse2.cpp227
-rw-r--r--src/block/idea_sse2/idea_sse2.h29
-rw-r--r--src/block/idea_sse2/info.txt7
-rw-r--r--src/build-data/buildh.in14
-rw-r--r--src/build-data/cc/msvc.txt2
-rw-r--r--src/build-data/innosetup.in2
-rw-r--r--src/build-data/os/linux.txt1
-rw-r--r--src/build-data/os/mingw.txt5
-rw-r--r--src/build-data/os/windows.txt4
-rw-r--r--src/cert/x509/pkcs10.cpp2
-rw-r--r--src/cert/x509/x509_ext.cpp5
-rw-r--r--src/cert/x509/x509opt.cpp2
-rw-r--r--src/constructs/tss/tss.h2
-rw-r--r--src/engine/simd_engine/simd_engine.cpp14
-rw-r--r--src/entropy/beos_stats/es_beos.cpp2
-rw-r--r--src/entropy/cryptoapi_rng/es_capi.cpp2
-rw-r--r--src/entropy/hres_timer/hres_timer.cpp2
-rw-r--r--src/entropy/win32_stats/es_win32.cpp2
-rw-r--r--src/filters/modes/cbc/cbc.cpp97
-rw-r--r--src/filters/modes/cbc/cbc.h56
-rw-r--r--src/filters/modes/cbc/info.txt1
-rw-r--r--src/filters/modes/cfb/cfb.cpp148
-rw-r--r--src/filters/modes/cfb/cfb.h55
-rw-r--r--src/filters/modes/cfb/info.txt4
-rw-r--r--src/filters/modes/cts/cts.cpp148
-rw-r--r--src/filters/modes/cts/cts.h52
-rw-r--r--src/filters/modes/cts/info.txt4
-rw-r--r--src/filters/modes/eax/eax.cpp99
-rw-r--r--src/filters/modes/eax/eax.h18
-rw-r--r--src/filters/modes/eax/eax_dec.cpp41
-rw-r--r--src/filters/modes/eax/info.txt2
-rw-r--r--src/filters/modes/ecb/ecb.h4
-rw-r--r--src/filters/modes/ecb/info.txt1
-rw-r--r--src/filters/modes/info.txt6
-rw-r--r--src/filters/modes/mode_pad/mode_pad.cpp3
-rw-r--r--src/filters/modes/modebase.cpp54
-rw-r--r--src/filters/modes/modebase.h44
-rw-r--r--src/filters/modes/xts/info.txt4
-rw-r--r--src/hash/skein/skein_512.cpp4
-rw-r--r--src/libstate/lookup.cpp4
-rw-r--r--src/math/numbertheory/numthry.cpp2
-rw-r--r--src/selftest/selftest.cpp6
-rw-r--r--src/utils/bswap.h50
-rw-r--r--src/utils/loadstor.h44
-rw-r--r--src/utils/time.cpp50
-rw-r--r--src/utils/xor_buf.h4
54 files changed, 1006 insertions, 509 deletions
diff --git a/checks/bench.cpp b/checks/bench.cpp
index e733c75ec..df346ec75 100644
--- a/checks/bench.cpp
+++ b/checks/bench.cpp
@@ -147,7 +147,7 @@ void report_results(const std::string& algo,
std::cout << " [" << i->second << "] "
<< std::fixed << std::setprecision(2) << i->first;
}
- std::cout << "\n";
+ std::cout << std::endl;
}
}
diff --git a/checks/check.cpp b/checks/check.cpp
index 8b31f354d..975315608 100644
--- a/checks/check.cpp
+++ b/checks/check.cpp
@@ -123,7 +123,7 @@ int main(int argc, char* argv[])
opts.is_set("benchmark") ||
opts.is_set("bench-type"))
{
- double seconds = 2;
+ double seconds = 5;
if(opts.is_set("seconds"))
{
diff --git a/checks/misc.cpp b/checks/misc.cpp
index 198671451..a49778dc6 100644
--- a/checks/misc.cpp
+++ b/checks/misc.cpp
@@ -43,7 +43,7 @@ SecureVector<byte> decode_hex(const std::string& in)
pipe.process_msg(in);
result = pipe.read_all();
}
- catch(std::exception& e)
+ catch(std::exception)
{
result.destroy();
}
diff --git a/checks/validate.dat b/checks/validate.dat
index ff2ed2f4b..9d319eaf3 100644
--- a/checks/validate.dat
+++ b/checks/validate.dat
@@ -4799,6 +4799,12 @@ D5D5D5D5D5D5D5D5:75F7C7005EA47839:D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5
0000000000000000:AA553A5DEC50E4A4:00000000000000040000000000000000
0000000000000001:0013FFF500120009:00000000000000000000000000000000
+000000010002000301020304050607080019324B647D96AFF5202D5B9C671B08\
+FAE6D2BEAA96826E0A141E28323C4650050A0F14191E2328050A0F14191E2328:\
+11FBED2B01986DE5540E5FEA18C2F8B19F0A0AB6E10CED78CF18FD7355E2C5C5\
+85DF52005608193D2F7DE750212FB7347B7314925DE59C097B7314925DE59C09:\
+00010002000300040005000600070008
+
# Test vectors taken from ARIB STD-T63-35.203 V6.0.0
[KASUMI]
EA024714AD5C4D84:DF1F9B251C0BF45F:2BD6459F82C5B300952C49104881FF48
@@ -23023,6 +23029,17 @@ AAE1BA501274C49A7A7EC67D7577114B7707DAB9D066AF086C09E7DD4116CEA6\
EE25DA9A65EF05A31ED0BDF56D525EC8968D1D01AF7165C5AEAC76BD367A575A:\
00000000000000000000000000000000
+[IDEA/ECB/NoPadding]
+000000010002000301020304050607080019324B647D96AFF5202D5B9C671B08\
+FAE6D2BEAA96826E0A141E28323C4650050A0F14191E2328050A0F14191E2328\
+000000010002000301020304050607080019324B647D96AFF5202D5B9C671B08\
+FAE6D2BEAA96826E0A141E28323C4650050A0F14191E2328050A0F14191E2328:\
+11FBED2B01986DE5540E5FEA18C2F8B19F0A0AB6E10CED78CF18FD7355E2C5C5\
+85DF52005608193D2F7DE750212FB7347B7314925DE59C097B7314925DE59C09\
+11FBED2B01986DE5540E5FEA18C2F8B19F0A0AB6E10CED78CF18FD7355E2C5C5\
+85DF52005608193D2F7DE750212FB7347B7314925DE59C097B7314925DE59C09:\
+00010002000300040005000600070008
+
[DES/ECB/NoPadding]
059B5E0851CF143A:86A560F10EC6D85B:0113B970FD34F2CE
4E6F772069732074:3FA40E8A984D4815:0123456789ABCDEF
diff --git a/configure.py b/configure.py
index 5298f7eb3..97e591b5d 100755
--- a/configure.py
+++ b/configure.py
@@ -121,6 +121,13 @@ class BuildConfigurationInformation(object):
Handle command line options
"""
def process_command_line(args):
+
+ # This is just an implementation of Optik's append_const action,
+ # but that is not available in Python 2.4's optparse, so use a
+ # callback instead
+ def optparse_append_const(option, opt, value, parser, dest, arg):
+ parser.values.__dict__[dest].append(arg)
+
parser = OptionParser(
formatter = IndentedHelpFormatter(max_help_position = 50),
version = BuildConfigurationInformation.version_string)
@@ -145,10 +152,34 @@ def process_command_line(args):
dest='unaligned_mem', action='store_false',
help=SUPPRESS_HELP)
- target_group.add_option('--with-isa-extension', metavar='ISALIST',
- dest='with_isa_extns',
+ target_group.add_option('--enable-isa', metavar='ISALIST',
+ dest='enable_isa_extns',
+ action='append', default=[],
+ help='enable ISA extensions')
+
+ target_group.add_option('--disable-isa', metavar='ISALIST',
+ dest='disable_isa_extns',
action='append', default=[],
- help='enable ISA extensions (sse2, altivec)')
+ help=SUPPRESS_HELP)
+
+ for isa_extn in ['sse2', 'ssse3', 'altivec', 'aes_ni']:
+ target_group.add_option('--enable-%s' % (isa_extn),
+ action='callback',
+ help=SUPPRESS_HELP,
+ callback=optparse_append_const,
+ callback_kwargs = {
+ 'dest': 'enable_isa_extns',
+ 'arg': isa_extn }
+ )
+
+ target_group.add_option('--disable-%s' % (isa_extn),
+ action='callback',
+ help=SUPPRESS_HELP,
+ callback=optparse_append_const,
+ callback_kwargs = {
+ 'dest': 'disable_isa_extns',
+ 'arg': isa_extn }
+ )
build_group = OptionGroup(parser, 'Build options')
@@ -208,25 +239,18 @@ def process_command_line(args):
for mod in ['openssl', 'gnump', 'bzip2', 'zlib']:
- # This is just an implementation of Optik's append_const action,
- # but that is not available in Python 2.4's optparse, so use a
- # callback instead
-
- def optparse_callback(option, opt, value, parser, dest, mod):
- parser.values.__dict__[dest].append(mod)
-
mods_group.add_option('--with-%s' % (mod),
action='callback',
- callback=optparse_callback,
+ callback=optparse_append_const,
callback_kwargs = {
- 'dest': 'enabled_modules', 'mod': mod }
+ 'dest': 'enabled_modules', 'arg': mod }
)
mods_group.add_option('--without-%s' % (mod), help=SUPPRESS_HELP,
action='callback',
- callback=optparse_callback,
+ callback=optparse_append_const,
callback_kwargs = {
- 'dest': 'disabled_modules', 'mod': mod }
+ 'dest': 'disabled_modules', 'arg': mod }
)
install_group = OptionGroup(parser, 'Installation options')
@@ -284,7 +308,8 @@ def process_command_line(args):
options.enabled_modules = parse_multiple_enable(options.enabled_modules)
options.disabled_modules = parse_multiple_enable(options.disabled_modules)
- options.with_isa_extns = parse_multiple_enable(options.with_isa_extns)
+ options.enable_isa_extns = parse_multiple_enable(options.enable_isa_extns)
+ options.disable_isa_extns = parse_multiple_enable(options.disable_isa_extns)
return options
@@ -443,9 +468,14 @@ class ModuleInfo(object):
return False
if self.need_isa != None:
- cpu_isa = archinfo.isa_extensions_in(cpu_name)
- if self.need_isa not in cpu_isa:
- return self.need_isa in options.with_isa_extns
+ if self.need_isa in options.disable_isa_extns:
+ return False # explicitly disabled
+
+ if self.need_isa in options.enable_isa_extns:
+ return True # explicitly enabled
+
+ # Default to whatever the CPU is supposed to support
+ return self.need_isa in archinfo.isa_extensions_in(cpu_name)
return True
@@ -532,12 +562,16 @@ class ArchInfo(object):
if self.basename != options.cpu:
macros.append('TARGET_CPU_IS_%s' % (form_cpu_macro(options.cpu)))
- isa_extensions = sorted(set(
- flatten([self.isa_extensions_in(options.cpu),
- options.with_isa_extns])))
+ enabled_isas = set(flatten(
+ [self.isa_extensions_in(options.cpu),
+ options.enable_isa_extns]))
+
+ disabled_isas = set(options.disable_isa_extns)
+
+ isa_extensions = sorted(enabled_isas - disabled_isas)
- for simd in isa_extensions:
- macros.append('TARGET_CPU_HAS_%s' % (simd.upper()))
+ for isa in isa_extensions:
+ macros.append('TARGET_CPU_HAS_%s' % (isa.upper()))
endian = options.with_endian or self.endian
diff --git a/doc/log.txt b/doc/log.txt
index 6334ee995..c150e6f66 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -1,5 +1,8 @@
* 1.9.4-dev, ????-??-??
+ - Add SSE2 implementation of IDEA
+ - Add support for Win32 high resolution system timers
+ - Remove Timer class entirely
- New option --gen-amalgamation for creating a SQLite-style amalgamation
- Many headers are now explicitly internal-use-only and are not installed
- Greatly improve the Win32 installer
diff --git a/src/block/idea/idea.cpp b/src/block/idea/idea.cpp
index fb5fe83f1..15ff7c0ec 100644
--- a/src/block/idea/idea.cpp
+++ b/src/block/idea/idea.cpp
@@ -55,13 +55,13 @@ u16bit mul_inv(u16bit x)
return (1 - t0);
}
-}
-
-/*
-* IDEA Encryption
+/**
+* IDEA is involutional, depending only on the key schedule
*/
-void IDEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
+void idea_op(const byte in[], byte out[], u32bit blocks, const u16bit K[52])
{
+ const u32bit BLOCK_SIZE = 8;
+
for(u32bit i = 0; i != blocks; ++i)
{
u16bit X1 = load_be<u16bit>(in, 0);
@@ -71,16 +71,16 @@ void IDEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
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]);
+ X1 = mul(X1, K[6*j+0]);
+ X2 += K[6*j+1];
+ X3 += K[6*j+2];
+ X4 = mul(X4, K[6*j+3]);
u16bit T0 = X3;
- X3 = mul(X3 ^ X1, EK[6*j+4]);
+ X3 = mul(X3 ^ X1, K[6*j+4]);
u16bit T1 = X2;
- X2 = mul((X2 ^ X4) + X3, EK[6*j+5]);
+ X2 = mul((X2 ^ X4) + X3, K[6*j+5]);
X3 += X2;
X1 ^= X2;
@@ -89,10 +89,10 @@ void IDEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
X3 ^= T1;
}
- X1 = mul(X1, EK[48]);
- X2 += EK[50];
- X3 += EK[49];
- X4 = mul(X4, EK[51]);
+ X1 = mul(X1, K[48]);
+ X2 += K[50];
+ X3 += K[49];
+ X4 = mul(X4, K[51]);
store_be(out, X1, X3, X2, X4);
@@ -101,48 +101,22 @@ void IDEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
}
}
+}
+
+/*
+* IDEA Encryption
+*/
+void IDEA::encrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ idea_op(in, out, blocks, EK);
+ }
+
/*
* IDEA Decryption
*/
void IDEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const
{
- for(u32bit i = 0; i != blocks; ++i)
- {
- 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;
- }
+ idea_op(in, out, blocks, DK);
}
/*
diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h
index c1a79f423..89ec117e3 100644
--- a/src/block/idea/idea.h
+++ b/src/block/idea/idea.h
@@ -26,7 +26,7 @@ class BOTAN_DLL IDEA : public BlockCipher
BlockCipher* clone() const { return new IDEA; }
IDEA() : BlockCipher(8, 16) {}
- private:
+ protected:
void key_schedule(const byte[], u32bit);
SecureBuffer<u16bit, 52> EK, DK;
};
diff --git a/src/block/idea_sse2/idea_sse2.cpp b/src/block/idea_sse2/idea_sse2.cpp
new file mode 100644
index 000000000..c00d13ee9
--- /dev/null
+++ b/src/block/idea_sse2/idea_sse2.cpp
@@ -0,0 +1,227 @@
+/*
+* IDEA in SSE2
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/idea_sse2.h>
+#include <botan/loadstor.h>
+#include <emmintrin.h>
+
+namespace Botan {
+
+namespace {
+
+inline __m128i mul(__m128i X, u16bit K_16)
+ {
+ const __m128i zeros = _mm_set1_epi16(0);
+ const __m128i ones = _mm_set1_epi16(1);
+ const __m128i high_bit = _mm_set1_epi16(0x8000);
+
+ const __m128i K = _mm_set1_epi16(K_16);
+
+ const __m128i X_is_zero = _mm_cmpeq_epi16(X, zeros);
+ const __m128i K_is_zero = _mm_cmpeq_epi16(K, zeros);
+
+ const __m128i mul_lo = _mm_mullo_epi16(X, K);
+ const __m128i mul_hi = _mm_mulhi_epu16(X, K);
+
+ __m128i T = _mm_sub_epi16(mul_lo, mul_hi);
+
+ // Unsigned compare; cmp = 1 if mul_lo < mul_hi else 0
+ const __m128i cmp = _mm_srli_epi16(_mm_cmpgt_epi16(
+ _mm_add_epi16(mul_hi, high_bit),
+ _mm_add_epi16(mul_lo, high_bit)),
+ 15);
+
+ T = _mm_add_epi16(T, cmp);
+
+ /* Selection: if X[i] is zero then assign 1-K
+ if K is zero then assign 1-X[i]
+
+ Could if() off value of K_16 for the second, but this gives a
+ constant time implementation which is a nice bonus.
+ */
+
+ T = _mm_or_si128(
+ _mm_andnot_si128(X_is_zero, T),
+ _mm_and_si128(_mm_sub_epi16(ones, K), X_is_zero));
+
+ T = _mm_or_si128(
+ _mm_andnot_si128(K_is_zero, T),
+ _mm_and_si128(_mm_sub_epi16(ones, X), K_is_zero));
+
+ return T;
+ }
+
+/*
+* 4x8 matrix transpose
+*
+* FIXME: why do I need the extra set of unpack_epi32 here? Inverse in
+* transpose_out doesn't need it. Something with the shuffle? Removing
+* that extra unpack could easily save 3-4 cycles per block, and would
+* also help a lot with register pressure on 32-bit x86
+*/
+void transpose_in(__m128i& B0, __m128i& B1, __m128i& B2, __m128i& B3)
+ {
+ __m128i T0 = _mm_unpackhi_epi32(B0, B1);
+ __m128i T1 = _mm_unpacklo_epi32(B0, B1);
+ __m128i T2 = _mm_unpackhi_epi32(B2, B3);
+ __m128i T3 = _mm_unpacklo_epi32(B2, B3);
+
+ __m128i T4 = _mm_unpacklo_epi32(T0, T1);
+ __m128i T5 = _mm_unpackhi_epi32(T0, T1);
+ __m128i T6 = _mm_unpacklo_epi32(T2, T3);
+ __m128i T7 = _mm_unpackhi_epi32(T2, T3);
+
+ T0 = _mm_shufflehi_epi16(T4, _MM_SHUFFLE(1, 3, 0, 2));
+ T1 = _mm_shufflehi_epi16(T5, _MM_SHUFFLE(1, 3, 0, 2));
+ T2 = _mm_shufflehi_epi16(T6, _MM_SHUFFLE(1, 3, 0, 2));
+ T3 = _mm_shufflehi_epi16(T7, _MM_SHUFFLE(1, 3, 0, 2));
+
+ T0 = _mm_shufflelo_epi16(T0, _MM_SHUFFLE(1, 3, 0, 2));
+ T1 = _mm_shufflelo_epi16(T1, _MM_SHUFFLE(1, 3, 0, 2));
+ T2 = _mm_shufflelo_epi16(T2, _MM_SHUFFLE(1, 3, 0, 2));
+ T3 = _mm_shufflelo_epi16(T3, _MM_SHUFFLE(1, 3, 0, 2));
+
+ T0 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 1, 2, 0));
+ T1 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(3, 1, 2, 0));
+ T2 = _mm_shuffle_epi32(T2, _MM_SHUFFLE(3, 1, 2, 0));
+ T3 = _mm_shuffle_epi32(T3, _MM_SHUFFLE(3, 1, 2, 0));
+
+ B0 = _mm_unpacklo_epi64(T0, T2);
+ B1 = _mm_unpackhi_epi64(T0, T2);
+ B2 = _mm_unpacklo_epi64(T1, T3);
+ B3 = _mm_unpackhi_epi64(T1, T3);
+ }
+
+/*
+* 4x8 matrix transpose (reverse)
+*/
+void transpose_out(__m128i& B0, __m128i& B1, __m128i& B2, __m128i& B3)
+ {
+ __m128i T0 = _mm_unpacklo_epi64(B0, B1);
+ __m128i T1 = _mm_unpacklo_epi64(B2, B3);
+ __m128i T2 = _mm_unpackhi_epi64(B0, B1);
+ __m128i T3 = _mm_unpackhi_epi64(B2, B3);
+
+ T0 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 1, 2, 0));
+ T1 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(3, 1, 2, 0));
+ T2 = _mm_shuffle_epi32(T2, _MM_SHUFFLE(3, 1, 2, 0));
+ T3 = _mm_shuffle_epi32(T3, _MM_SHUFFLE(3, 1, 2, 0));
+
+ T0 = _mm_shufflehi_epi16(T0, _MM_SHUFFLE(3, 1, 2, 0));
+ T1 = _mm_shufflehi_epi16(T1, _MM_SHUFFLE(3, 1, 2, 0));
+ T2 = _mm_shufflehi_epi16(T2, _MM_SHUFFLE(3, 1, 2, 0));
+ T3 = _mm_shufflehi_epi16(T3, _MM_SHUFFLE(3, 1, 2, 0));
+
+ T0 = _mm_shufflelo_epi16(T0, _MM_SHUFFLE(3, 1, 2, 0));
+ T1 = _mm_shufflelo_epi16(T1, _MM_SHUFFLE(3, 1, 2, 0));
+ T2 = _mm_shufflelo_epi16(T2, _MM_SHUFFLE(3, 1, 2, 0));
+ T3 = _mm_shufflelo_epi16(T3, _MM_SHUFFLE(3, 1, 2, 0));
+
+ B0 = _mm_unpacklo_epi32(T0, T1);
+ B1 = _mm_unpackhi_epi32(T0, T1);
+ B2 = _mm_unpacklo_epi32(T2, T3);
+ B3 = _mm_unpackhi_epi32(T2, T3);
+ }
+
+/*
+* IDEA encryption/decryption in SSE2
+*/
+void idea_op_8(const byte in[64], byte out[64], const u16bit EK[52])
+ {
+ __m128i B0 = _mm_loadu_si128((const __m128i*)in);
+ __m128i B1 = _mm_loadu_si128((const __m128i*)in + 1);
+ __m128i B2 = _mm_loadu_si128((const __m128i*)in + 2);
+ __m128i B3 = _mm_loadu_si128((const __m128i*)in + 3);
+
+ transpose_in(B0, B1, B2, B3);
+
+ // byte swap
+ B0 = _mm_or_si128(_mm_slli_epi16(B0, 8), _mm_srli_epi16(B0, 8));
+ B1 = _mm_or_si128(_mm_slli_epi16(B1, 8), _mm_srli_epi16(B1, 8));
+ B2 = _mm_or_si128(_mm_slli_epi16(B2, 8), _mm_srli_epi16(B2, 8));
+ B3 = _mm_or_si128(_mm_slli_epi16(B3, 8), _mm_srli_epi16(B3, 8));
+
+ for(u32bit i = 0; i != 8; ++i)
+ {
+ B0 = mul(B0, EK[6*i+0]);
+ B1 = _mm_add_epi16(B1, _mm_set1_epi16(EK[6*i+1]));
+ B2 = _mm_add_epi16(B2, _mm_set1_epi16(EK[6*i+2]));
+ B3 = mul(B3, EK[6*i+3]);
+
+ __m128i T0 = B2;
+
+ B2 = _mm_xor_si128(B2, B0);
+ B2 = mul(B2, EK[6*i+4]);
+
+ __m128i T1 = B1;
+
+ B1 = _mm_xor_si128(B1, B3);
+ B1 = _mm_add_epi16(B1, B2);
+ B1 = mul(B1, EK[6*i+5]);
+
+ B2 = _mm_add_epi16(B2, B1);
+
+ B0 = _mm_xor_si128(B0, B1);
+ B1 = _mm_xor_si128(B1, T0);
+ B3 = _mm_xor_si128(B3, B2);
+ B2 = _mm_xor_si128(B2, T1);
+ }
+
+ B0 = mul(B0, EK[48]);
+ B1 = _mm_add_epi16(B1, _mm_set1_epi16(EK[50]));
+ B2 = _mm_add_epi16(B2, _mm_set1_epi16(EK[49]));
+ B3 = mul(B3, EK[51]);
+
+ // byte swap
+ B0 = _mm_or_si128(_mm_slli_epi16(B0, 8), _mm_srli_epi16(B0, 8));
+ B1 = _mm_or_si128(_mm_slli_epi16(B1, 8), _mm_srli_epi16(B1, 8));
+ B2 = _mm_or_si128(_mm_slli_epi16(B2, 8), _mm_srli_epi16(B2, 8));
+ B3 = _mm_or_si128(_mm_slli_epi16(B3, 8), _mm_srli_epi16(B3, 8));
+
+ transpose_out(B0, B2, B1, B3);
+
+ _mm_storeu_si128((__m128i*)out, B0);
+ _mm_storeu_si128((__m128i*)out + 1, B2);
+ _mm_storeu_si128((__m128i*)out + 2, B1);
+ _mm_storeu_si128((__m128i*)out + 3, B3);
+ }
+
+}
+
+/*
+* IDEA Encryption
+*/
+void IDEA_SSE2::encrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 8)
+ {
+ idea_op_8(in, out, this->EK);
+ in += 8 * BLOCK_SIZE;
+ out += 8 * BLOCK_SIZE;
+ blocks -= 8;
+ }
+
+ IDEA::encrypt_n(in, out, blocks);
+ }
+
+/*
+* IDEA Decryption
+*/
+void IDEA_SSE2::decrypt_n(const byte in[], byte out[], u32bit blocks) const
+ {
+ while(blocks >= 8)
+ {
+ idea_op_8(in, out, this->DK);
+ in += 8 * BLOCK_SIZE;
+ out += 8 * BLOCK_SIZE;
+ blocks -= 8;
+ }
+
+ IDEA::decrypt_n(in, out, blocks);
+ }
+
+}
diff --git a/src/block/idea_sse2/idea_sse2.h b/src/block/idea_sse2/idea_sse2.h
new file mode 100644
index 000000000..167c981f8
--- /dev/null
+++ b/src/block/idea_sse2/idea_sse2.h
@@ -0,0 +1,29 @@
+/*
+* IDEA in SSE2
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_IDEA_SSE2_H__
+#define BOTAN_IDEA_SSE2_H__
+
+#include <botan/idea.h>
+
+namespace Botan {
+
+/*
+* IDEA in SSE2
+*/
+class BOTAN_DLL IDEA_SSE2 : public IDEA
+ {
+ 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 IDEA_SSE2; }
+ };
+
+}
+
+#endif
diff --git a/src/block/idea_sse2/info.txt b/src/block/idea_sse2/info.txt
new file mode 100644
index 000000000..fe09d3ee5
--- /dev/null
+++ b/src/block/idea_sse2/info.txt
@@ -0,0 +1,7 @@
+define IDEA_SSE2
+
+need_isa sse2
+
+<requires>
+idea
+</requires>
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index 9d7012a73..7588dc99b 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -30,8 +30,7 @@
#define BOTAN_PARALLEL_BLOCKS_ECB 8
#define BOTAN_PARALLEL_BLOCKS_CBC 8
#define BOTAN_PARALLEL_BLOCKS_CFB 8
-#define BOTAN_PARALLEL_BLOCKS_CTR 8
-#define BOTAN_PARALLEL_BLOCKS_EAX 8
+#define BOTAN_PARALLEL_BLOCKS_CTR 16
#define BOTAN_PARALLEL_BLOCKS_XTS 8
/* PK key consistency checking toggles */
@@ -53,8 +52,19 @@
%{target_cpu_defines}
+#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) || \
+ defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+ #define BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS
+#endif
+
%{target_compiler_defines}
+#if defined(BOTAN_BUILD_COMPILER_IS_MSVC)
+ // 4250: inherits via dominance (diamond inheritence issue)
+ // 4251: needs DLL interface (STL DLL exports)
+ #pragma warning(disable: 4250 4251)
+#endif
+
/* Module definitions */
%{module_defines}
diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt
index 892e80c4b..36437e6a2 100644
--- a/src/build-data/cc/msvc.txt
+++ b/src/build-data/cc/msvc.txt
@@ -12,7 +12,7 @@ no_debug_flags "/O2"
debug_flags "/Od /Zi /DDEBUG"
check_opt_flags "/O2 /D_CONSOLE"
lang_flags "/EHsc /GR"
-warning_flags ""
+warning_flags "/W3"
shared_flags "/DBOTAN_DLL=__declspec(dllexport)"
dll_import_flags "__declspec(dllimport)"
diff --git a/src/build-data/innosetup.in b/src/build-data/innosetup.in
index 228ab4e97..c3e0f1ebd 100644
--- a/src/build-data/innosetup.in
+++ b/src/build-data/innosetup.in
@@ -9,7 +9,7 @@ AppPublisherURL=http://botan.randombit.net/
AppVersion=%{version}
VersionInfoCopyright=Copyright (C) 1999-2009 Jack Lloyd and others
-VersionInfoVersion=%{version}.0
+VersionInfoVersion=%{version_major}.%{version_minor}.%{version_patch}.0
; Require at least Windows 98 or 2000
MinVersion=4.1,5.0
diff --git a/src/build-data/os/linux.txt b/src/build-data/os/linux.txt
index b3c227533..2f59fb9d1 100644
--- a/src/build-data/os/linux.txt
+++ b/src/build-data/os/linux.txt
@@ -4,6 +4,7 @@ os_type unix
clock_gettime
gettimeofday
posix_mlock
+gmtime_r
</target_features>
# Is this correct?
diff --git a/src/build-data/os/mingw.txt b/src/build-data/os/mingw.txt
index 2b7a16cf7..1b30e0b3a 100644
--- a/src/build-data/os/mingw.txt
+++ b/src/build-data/os/mingw.txt
@@ -19,3 +19,8 @@ install_cmd_exec "install -m 755"
msys
mingw32
</aliases>
+
+<target_features>
+win32_virtual_lock
+win32_get_systemtime
+</target_features>
diff --git a/src/build-data/os/windows.txt b/src/build-data/os/windows.txt
index 59e3ec072..23838eb6d 100644
--- a/src/build-data/os/windows.txt
+++ b/src/build-data/os/windows.txt
@@ -11,8 +11,10 @@ install_cmd_data "copy"
install_cmd_exec "copy"
<target_features>
-win32_virtual_lock
+gmtime_s
+win32_get_systemtime
win32_query_perf_counter
+win32_virtual_lock
</target_features>
<supports_shared>
diff --git a/src/cert/x509/pkcs10.cpp b/src/cert/x509/pkcs10.cpp
index 5645552a0..e78439757 100644
--- a/src/cert/x509/pkcs10.cpp
+++ b/src/cert/x509/pkcs10.cpp
@@ -186,7 +186,7 @@ std::vector<OID> PKCS10_Request::ex_constraints() const
*/
bool PKCS10_Request::is_CA() const
{
- return info.get1_u32bit("X509v3.BasicConstraints.is_ca");
+ return (info.get1_u32bit("X509v3.BasicConstraints.is_ca") > 0);
}
/*
diff --git a/src/cert/x509/x509_ext.cpp b/src/cert/x509/x509_ext.cpp
index e88b5a268..9a03c9d23 100644
--- a/src/cert/x509/x509_ext.cpp
+++ b/src/cert/x509/x509_ext.cpp
@@ -471,8 +471,10 @@ class Policy_Information : public ASN1_Object
*/
MemoryVector<byte> Certificate_Policies::encode_inner() const
{
+ // FIXME
+#if 1
throw Exception("Certificate_Policies::encode_inner: Bugged");
-
+#else
std::vector<Policy_Information> policies;
return DER_Encoder()
@@ -480,6 +482,7 @@ MemoryVector<byte> Certificate_Policies::encode_inner() const
.encode_list(policies)
.end_cons()
.get_contents();
+#endif
}
/*
diff --git a/src/cert/x509/x509opt.cpp b/src/cert/x509/x509opt.cpp
index 8d235ad5d..fda889224 100644
--- a/src/cert/x509/x509opt.cpp
+++ b/src/cert/x509/x509opt.cpp
@@ -78,7 +78,7 @@ void X509_Cert_Options::sanity_check() const
* Initialize the certificate options
*/
X509_Cert_Options::X509_Cert_Options(const std::string& initial_opts,
- u32bit expiration_time)
+ u32bit expiration_time_in_seconds)
{
is_CA = false;
path_limit = 0;
diff --git a/src/constructs/tss/tss.h b/src/constructs/tss/tss.h
index 45d64d9cb..c8b0242d8 100644
--- a/src/constructs/tss/tss.h
+++ b/src/constructs/tss/tss.h
@@ -45,7 +45,7 @@ class BOTAN_DLL RTSS_Share
byte share_id() const;
u32bit size() const { return contents.size(); }
- bool initialized() const { return contents.size(); }
+ bool initialized() const { return (contents.size() > 0); }
private:
SecureVector<byte> contents;
};
diff --git a/src/engine/simd_engine/simd_engine.cpp b/src/engine/simd_engine/simd_engine.cpp
index 892221f22..b8ebd6a80 100644
--- a/src/engine/simd_engine/simd_engine.cpp
+++ b/src/engine/simd_engine/simd_engine.cpp
@@ -17,6 +17,10 @@
#include <botan/xtea_simd.h>
#endif
+#if defined(BOTAN_HAS_IDEA_SSE2)
+ #include <botan/idea_sse2.h>
+#endif
+
#if defined(BOTAN_HAS_SHA1_SSE2)
#include <botan/sha1_sse2.h>
#endif
@@ -27,16 +31,18 @@ BlockCipher*
SIMD_Engine::find_block_cipher(const SCAN_Name& request,
Algorithm_Factory&) const
{
- if(!SIMD_32::enabled())
- return 0;
+#if defined(BOTAN_HAS_IDEA_SSE2)
+ if(request.algo_name() == "IDEA" && CPUID::has_sse2())
+ return new IDEA_SSE2;
+#endif
#if defined(BOTAN_HAS_SERPENT_SIMD)
- if(request.algo_name() == "Serpent")
+ if(request.algo_name() == "Serpent" && SIMD_32::enabled())
return new Serpent_SIMD;
#endif
#if defined(BOTAN_HAS_XTEA_SIMD)
- if(request.algo_name() == "XTEA")
+ if(request.algo_name() == "XTEA" && SIMD_32::enabled())
return new XTEA_SIMD;
#endif
diff --git a/src/entropy/beos_stats/es_beos.cpp b/src/entropy/beos_stats/es_beos.cpp
index 18eca5511..148d38b9b 100644
--- a/src/entropy/beos_stats/es_beos.cpp
+++ b/src/entropy/beos_stats/es_beos.cpp
@@ -5,7 +5,7 @@
* Distributed under the terms of the Botan license
*/
-#include <botan/es_beos.h>
+#include <botan/internal/es_beos.h>
#include <kernel/OS.h>
#include <kernel/image.h>
diff --git a/src/entropy/cryptoapi_rng/es_capi.cpp b/src/entropy/cryptoapi_rng/es_capi.cpp
index a70b52044..367166c62 100644
--- a/src/entropy/cryptoapi_rng/es_capi.cpp
+++ b/src/entropy/cryptoapi_rng/es_capi.cpp
@@ -5,7 +5,7 @@
* Distributed under the terms of the Botan license
*/
-#include <botan/es_capi.h>
+#include <botan/internal/es_capi.h>
#include <botan/parsing.h>
#include <windows.h>
#include <wincrypt.h>
diff --git a/src/entropy/hres_timer/hres_timer.cpp b/src/entropy/hres_timer/hres_timer.cpp
index 3e7c235ca..9f0a25c9b 100644
--- a/src/entropy/hres_timer/hres_timer.cpp
+++ b/src/entropy/hres_timer/hres_timer.cpp
@@ -25,7 +25,7 @@ void High_Resolution_Timestamp::poll(Entropy_Accumulator& accum)
accum.add(tv.QuadPart, 0);
#endif
-#if defined(BOTAN_USE_GCC_INLINE_ASM)
+#if BOTAN_USE_GCC_INLINE_ASM
u64bit rtc = 0;
diff --git a/src/entropy/win32_stats/es_win32.cpp b/src/entropy/win32_stats/es_win32.cpp
index a8e9e40f5..e9f564fee 100644
--- a/src/entropy/win32_stats/es_win32.cpp
+++ b/src/entropy/win32_stats/es_win32.cpp
@@ -5,7 +5,7 @@
* Distributed under the terms of the Botan license
*/
-#include <botan/es_win32.h>
+#include <botan/internal/es_win32.h>
#include <windows.h>
#include <tlhelp32.h>
diff --git a/src/filters/modes/cbc/cbc.cpp b/src/filters/modes/cbc/cbc.cpp
index a52f4b2e1..48ecdf509 100644
--- a/src/filters/modes/cbc/cbc.cpp
+++ b/src/filters/modes/cbc/cbc.cpp
@@ -16,11 +16,14 @@ namespace Botan {
*/
CBC_Encryption::CBC_Encryption(BlockCipher* ciph,
BlockCipherModePaddingMethod* pad) :
- BlockCipherMode(ciph, "CBC", ciph->BLOCK_SIZE),
- padder(pad)
+ cipher(ciph), padder(pad)
{
- if(!padder->valid_blocksize(BLOCK_SIZE))
+ if(!padder->valid_blocksize(cipher->BLOCK_SIZE))
throw Invalid_Block_Size(name(), padder->name());
+
+ buffer.resize(cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ position = 0;
}
/*
@@ -30,31 +33,48 @@ CBC_Encryption::CBC_Encryption(BlockCipher* ciph,
BlockCipherModePaddingMethod* pad,
const SymmetricKey& key,
const InitializationVector& iv) :
- BlockCipherMode(ciph, "CBC", ciph->BLOCK_SIZE),
- padder(pad)
+ cipher(ciph), padder(pad)
{
- if(!padder->valid_blocksize(BLOCK_SIZE))
+ if(!padder->valid_blocksize(cipher->BLOCK_SIZE))
throw Invalid_Block_Size(name(), padder->name());
+
+ buffer.resize(cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ position = 0;
+
set_key(key);
set_iv(iv);
}
/*
+* Set the IV
+*/
+void CBC_Encryption::set_iv(const InitializationVector& iv)
+ {
+ if(iv.length() != state.size())
+ throw Invalid_IV_Length(name(), iv.length());
+
+ state = iv.bits_of();
+ buffer.clear();
+ position = 0;
+ }
+
+/*
* Encrypt in CBC mode
*/
void CBC_Encryption::write(const byte input[], u32bit length)
{
while(length)
{
- u32bit xored = std::min(BLOCK_SIZE - position, length);
+ u32bit xored = std::min(cipher->BLOCK_SIZE - position, length);
xor_buf(state + position, input, xored);
input += xored;
length -= xored;
position += xored;
- if(position == BLOCK_SIZE)
+ if(position == cipher->BLOCK_SIZE)
{
cipher->encrypt(state);
- send(state, BLOCK_SIZE);
+ send(state, cipher->BLOCK_SIZE);
position = 0;
}
}
@@ -65,9 +85,9 @@ void CBC_Encryption::write(const byte input[], u32bit length)
*/
void CBC_Encryption::end_msg()
{
- SecureVector<byte> padding(BLOCK_SIZE);
+ SecureVector<byte> padding(cipher->BLOCK_SIZE);
padder->pad(padding, padding.size(), position);
- write(padding, padder->pad_bytes(BLOCK_SIZE, position));
+ write(padding, padder->pad_bytes(cipher->BLOCK_SIZE, position));
if(position != 0)
throw Exception(name() + ": Did not pad to full blocksize");
}
@@ -77,7 +97,7 @@ void CBC_Encryption::end_msg()
*/
std::string CBC_Encryption::name() const
{
- return (cipher->name() + "/" + mode_name + "/" + padder->name());
+ return (cipher->name() + "/CBC/" + padder->name());
}
/*
@@ -85,12 +105,15 @@ std::string CBC_Encryption::name() const
*/
CBC_Decryption::CBC_Decryption(BlockCipher* ciph,
BlockCipherModePaddingMethod* pad) :
- BlockCipherMode(ciph, "CBC", ciph->BLOCK_SIZE),
- padder(pad)
+ cipher(ciph), padder(pad)
{
- if(!padder->valid_blocksize(BLOCK_SIZE))
+ if(!padder->valid_blocksize(cipher->BLOCK_SIZE))
throw Invalid_Block_Size(name(), padder->name());
- temp.resize(BLOCK_SIZE);
+
+ buffer.resize(cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ temp.resize(cipher->BLOCK_SIZE);
+ position = 0;
}
/*
@@ -100,32 +123,50 @@ CBC_Decryption::CBC_Decryption(BlockCipher* ciph,
BlockCipherModePaddingMethod* pad,
const SymmetricKey& key,
const InitializationVector& iv) :
- BlockCipherMode(ciph, "CBC", ciph->BLOCK_SIZE),
- padder(pad)
+ cipher(ciph), padder(pad)
{
- if(!padder->valid_blocksize(BLOCK_SIZE))
+ if(!padder->valid_blocksize(cipher->BLOCK_SIZE))
throw Invalid_Block_Size(name(), padder->name());
- temp.resize(BLOCK_SIZE);
+
+ buffer.resize(cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ temp.resize(cipher->BLOCK_SIZE);
+ position = 0;
+
set_key(key);
set_iv(iv);
}
/*
+* Set the IV
+*/
+void CBC_Decryption::set_iv(const InitializationVector& iv)
+ {
+ if(iv.length() != state.size())
+ throw Invalid_IV_Length(name(), iv.length());
+
+ state = iv.bits_of();
+ buffer.clear();
+ position = 0;
+ }
+
+/*
* Decrypt in CBC mode
*/
void CBC_Decryption::write(const byte input[], u32bit length)
{
while(length)
{
- if(position == BLOCK_SIZE)
+ if(position == cipher->BLOCK_SIZE)
{
cipher->decrypt(buffer, temp);
- xor_buf(temp, state, BLOCK_SIZE);
- send(temp, BLOCK_SIZE);
+ xor_buf(temp, state, cipher->BLOCK_SIZE);
+ send(temp, cipher->BLOCK_SIZE);
state = buffer;
position = 0;
}
- u32bit added = std::min(BLOCK_SIZE - position, length);
+
+ u32bit added = std::min(cipher->BLOCK_SIZE - position, length);
buffer.copy(position, input, added);
input += added;
length -= added;
@@ -138,11 +179,11 @@ void CBC_Decryption::write(const byte input[], u32bit length)
*/
void CBC_Decryption::end_msg()
{
- if(position != BLOCK_SIZE)
+ if(position != cipher->BLOCK_SIZE)
throw Decoding_Error(name());
cipher->decrypt(buffer, temp);
- xor_buf(temp, state, BLOCK_SIZE);
- send(temp, padder->unpad(temp, BLOCK_SIZE));
+ xor_buf(temp, state, cipher->BLOCK_SIZE);
+ send(temp, padder->unpad(temp, cipher->BLOCK_SIZE));
state = buffer;
position = 0;
}
@@ -152,7 +193,7 @@ void CBC_Decryption::end_msg()
*/
std::string CBC_Decryption::name() const
{
- return (cipher->name() + "/" + mode_name + "/" + padder->name());
+ return (cipher->name() + "/CBC/" + padder->name());
}
}
diff --git a/src/filters/modes/cbc/cbc.h b/src/filters/modes/cbc/cbc.h
index a926ac180..91ab21ab6 100644
--- a/src/filters/modes/cbc/cbc.h
+++ b/src/filters/modes/cbc/cbc.h
@@ -8,7 +8,8 @@
#ifndef BOTAN_CBC_H__
#define BOTAN_CBC_H__
-#include <botan/modebase.h>
+#include <botan/block_cipher.h>
+#include <botan/key_filt.h>
#include <botan/mode_pad.h>
namespace Botan {
@@ -16,38 +17,69 @@ namespace Botan {
/*
* CBC Encryption
*/
-class BOTAN_DLL CBC_Encryption : public BlockCipherMode
+class BOTAN_DLL CBC_Encryption : public Keyed_Filter
{
public:
- CBC_Encryption(BlockCipher*, BlockCipherModePaddingMethod*);
- CBC_Encryption(BlockCipher*, BlockCipherModePaddingMethod*,
- const SymmetricKey&, const InitializationVector&);
+ 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); }
+
+ CBC_Encryption(BlockCipher* cipher,
+ BlockCipherModePaddingMethod* padding);
+
+ CBC_Encryption(BlockCipher* cipher,
+ BlockCipherModePaddingMethod* padding,
+ const SymmetricKey& key,
+ const InitializationVector& iv);
~CBC_Encryption() { delete padder; }
private:
- std::string name() const;
void write(const byte[], u32bit);
void end_msg();
+
+ BlockCipher* cipher;
const BlockCipherModePaddingMethod* padder;
+ SecureVector<byte> buffer, state;
+ u32bit position;
};
/*
* CBC Decryption
*/
-class BOTAN_DLL CBC_Decryption : public BlockCipherMode
+class BOTAN_DLL CBC_Decryption : public Keyed_Filter
{
public:
- CBC_Decryption(BlockCipher*, BlockCipherModePaddingMethod*);
- CBC_Decryption(BlockCipher*, BlockCipherModePaddingMethod*,
- const SymmetricKey&, const InitializationVector&);
+ 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); }
+
+ CBC_Decryption(BlockCipher* cipher,
+ BlockCipherModePaddingMethod* padding);
+
+ CBC_Decryption(BlockCipher* cipher,
+ BlockCipherModePaddingMethod* padding,
+ const SymmetricKey& key,
+ const InitializationVector& iv);
~CBC_Decryption() { delete padder; }
private:
- std::string name() const;
void write(const byte[], u32bit);
void end_msg();
+
+ BlockCipher* cipher;
const BlockCipherModePaddingMethod* padder;
- SecureVector<byte> temp;
+ SecureVector<byte> buffer, state, temp;
+ u32bit position;
};
}
diff --git a/src/filters/modes/cbc/info.txt b/src/filters/modes/cbc/info.txt
index 92a39d674..229edfbf7 100644
--- a/src/filters/modes/cbc/info.txt
+++ b/src/filters/modes/cbc/info.txt
@@ -1,5 +1,6 @@
define CBC
<requires>
+block
mode_pad
</requires>
diff --git a/src/filters/modes/cfb/cfb.cpp b/src/filters/modes/cfb/cfb.cpp
index 5456bbe0f..e7737e673 100644
--- a/src/filters/modes/cfb/cfb.cpp
+++ b/src/filters/modes/cfb/cfb.cpp
@@ -12,30 +12,21 @@
namespace Botan {
-namespace {
-
/*
-* Check the feedback size
+* CFB Encryption Constructor
*/
-void check_feedback(u32bit BLOCK_SIZE, u32bit FEEDBACK_SIZE, u32bit bits,
- const std::string& name)
+CFB_Encryption::CFB_Encryption(BlockCipher* ciph, u32bit fback_bits)
{
- if(FEEDBACK_SIZE == 0 || FEEDBACK_SIZE > BLOCK_SIZE || bits % 8 != 0)
- throw Invalid_Argument(name + ": Invalid feedback size " +
- std::to_string(bits));
- }
+ cipher = ciph;
+ feedback = fback_bits ? fback_bits / 8: cipher->BLOCK_SIZE;
-}
+ buffer.resize(cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ position = 0;
-/*
-* CFB Encryption Constructor
-*/
-CFB_Encryption::CFB_Encryption(BlockCipher* ciph,
- u32bit fback_bits) :
- BlockCipherMode(ciph, "CFB", ciph->BLOCK_SIZE, 1),
- FEEDBACK_SIZE(fback_bits ? fback_bits / 8: BLOCK_SIZE)
- {
- check_feedback(BLOCK_SIZE, FEEDBACK_SIZE, fback_bits, name());
+ if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->BLOCK_SIZE)
+ throw Invalid_Argument("CFB_Encryption: Invalid feedback size " +
+ std::to_string(fback_bits));
}
/*
@@ -44,15 +35,35 @@ CFB_Encryption::CFB_Encryption(BlockCipher* ciph,
CFB_Encryption::CFB_Encryption(BlockCipher* ciph,
const SymmetricKey& key,
const InitializationVector& iv,
- u32bit fback_bits) :
- BlockCipherMode(ciph, "CFB", ciph->BLOCK_SIZE, 1),
- FEEDBACK_SIZE(fback_bits ? fback_bits / 8: BLOCK_SIZE)
+ u32bit fback_bits)
{
- check_feedback(BLOCK_SIZE, FEEDBACK_SIZE, fback_bits, name());
+ cipher = ciph;
+ feedback = fback_bits ? fback_bits / 8: cipher->BLOCK_SIZE;
+
+ buffer.resize(cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ position = 0;
+
+ if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->BLOCK_SIZE)
+ throw Invalid_Argument("CFB_Encryption: Invalid feedback size " +
+ std::to_string(fback_bits));
+
set_key(key);
set_iv(iv);
}
+void CFB_Encryption::set_iv(const InitializationVector& iv)
+ {
+ if(iv.length() != state.size())
+ throw Invalid_IV_Length(name(), iv.length());
+
+ state = iv.bits_of();
+ buffer.clear();
+ position = 0;
+
+ cipher->encrypt(state, buffer);
+ }
+
/*
* Encrypt data in CFB mode
*/
@@ -60,38 +71,39 @@ void CFB_Encryption::write(const byte input[], u32bit length)
{
while(length)
{
- u32bit xored = std::min(FEEDBACK_SIZE - position, length);
+ u32bit xored = std::min(feedback - position, length);
xor_buf(buffer + position, input, xored);
send(buffer + position, xored);
input += xored;
length -= xored;
position += xored;
- if(position == FEEDBACK_SIZE)
- feedback();
+
+ if(position == feedback)
+ {
+ for(u32bit j = 0; j != cipher->BLOCK_SIZE - feedback; ++j)
+ state[j] = state[j + feedback];
+ state.copy(cipher->BLOCK_SIZE - feedback, buffer, feedback);
+ cipher->encrypt(state, buffer);
+ position = 0;
+ }
}
}
/*
-* Do the feedback
+* CFB Decryption Constructor
*/
-void CFB_Encryption::feedback()
+CFB_Decryption::CFB_Decryption(BlockCipher* ciph, u32bit fback_bits)
{
- for(u32bit j = 0; j != BLOCK_SIZE - FEEDBACK_SIZE; ++j)
- state[j] = state[j + FEEDBACK_SIZE];
- state.copy(BLOCK_SIZE - FEEDBACK_SIZE, buffer, FEEDBACK_SIZE);
- cipher->encrypt(state, buffer);
+ cipher = ciph;
+ feedback = fback_bits ? fback_bits / 8: cipher->BLOCK_SIZE;
+
+ buffer.resize(cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
position = 0;
- }
-/*
-* CFB Decryption Constructor
-*/
-CFB_Decryption::CFB_Decryption(BlockCipher* ciph,
- u32bit fback_bits) :
- BlockCipherMode(ciph, "CFB", ciph->BLOCK_SIZE, 1),
- FEEDBACK_SIZE(fback_bits ? fback_bits / 8 : BLOCK_SIZE)
- {
- check_feedback(BLOCK_SIZE, FEEDBACK_SIZE, fback_bits, name());
+ if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->BLOCK_SIZE)
+ throw Invalid_Argument("CFB_Decryption: Invalid feedback size " +
+ to_string(fback_bits));
}
/*
@@ -100,15 +112,35 @@ CFB_Decryption::CFB_Decryption(BlockCipher* ciph,
CFB_Decryption::CFB_Decryption(BlockCipher* ciph,
const SymmetricKey& key,
const InitializationVector& iv,
- u32bit fback_bits) :
- BlockCipherMode(ciph, "CFB", ciph->BLOCK_SIZE, 1),
- FEEDBACK_SIZE(fback_bits ? fback_bits / 8 : BLOCK_SIZE)
+ u32bit fback_bits)
{
- check_feedback(BLOCK_SIZE, FEEDBACK_SIZE, fback_bits, name());
+ cipher = ciph;
+ feedback = fback_bits ? fback_bits / 8: cipher->BLOCK_SIZE;
+
+ buffer.resize(cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ position = 0;
+
+ if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->BLOCK_SIZE)
+ throw Invalid_Argument("CFB_Decryption: Invalid feedback size " +
+ to_string(fback_bits));
+
set_key(key);
set_iv(iv);
}
+void CFB_Decryption::set_iv(const InitializationVector& iv)
+ {
+ if(iv.length() != state.size())
+ throw Invalid_IV_Length(name(), iv.length());
+
+ state = iv.bits_of();
+ buffer.clear();
+ position = 0;
+
+ cipher->encrypt(state, buffer);
+ }
+
/*
* Decrypt data in CFB mode
*/
@@ -116,28 +148,22 @@ void CFB_Decryption::write(const byte input[], u32bit length)
{
while(length)
{
- u32bit xored = std::min(FEEDBACK_SIZE - position, length);
+ u32bit xored = std::min(feedback - position, length);
xor_buf(buffer + position, input, xored);
send(buffer + position, xored);
buffer.copy(position, input, xored);
input += xored;
length -= xored;
position += xored;
- if(position == FEEDBACK_SIZE)
- feedback();
+ if(position == feedback)
+ {
+ for(u32bit j = 0; j != cipher->BLOCK_SIZE - feedback; ++j)
+ state[j] = state[j + feedback];
+ state.copy(cipher->BLOCK_SIZE - feedback, buffer, feedback);
+ cipher->encrypt(state, buffer);
+ position = 0;
+ }
}
}
-/*
-* Do the feedback
-*/
-void CFB_Decryption::feedback()
- {
- for(u32bit j = 0; j != BLOCK_SIZE - FEEDBACK_SIZE; ++j)
- state[j] = state[j + FEEDBACK_SIZE];
- state.copy(BLOCK_SIZE - FEEDBACK_SIZE, buffer, FEEDBACK_SIZE);
- cipher->encrypt(state, buffer);
- position = 0;
- }
-
}
diff --git a/src/filters/modes/cfb/cfb.h b/src/filters/modes/cfb/cfb.h
index 7810c00e4..917125e46 100644
--- a/src/filters/modes/cfb/cfb.h
+++ b/src/filters/modes/cfb/cfb.h
@@ -8,38 +8,67 @@
#ifndef BOTAN_CFB_H__
#define BOTAN_CFB_H__
-#include <botan/modebase.h>
+#include <botan/block_cipher.h>
+#include <botan/key_filt.h>
namespace Botan {
/*
* CFB Encryption
*/
-class BOTAN_DLL CFB_Encryption : public BlockCipherMode
+class BOTAN_DLL CFB_Encryption : public Keyed_Filter
{
public:
- CFB_Encryption(BlockCipher*, u32bit = 0);
- CFB_Encryption(BlockCipher*, const SymmetricKey&,
- const InitializationVector&, u32bit = 0);
+ std::string name() const { return cipher->name() + "/CFB"; }
+
+ 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); }
+
+ CFB_Encryption(BlockCipher* cipher, u32bit feedback = 0);
+
+ CFB_Encryption(BlockCipher* cipher,
+ const SymmetricKey& key,
+ const InitializationVector& iv,
+ u32bit feedback = 0);
private:
void write(const byte[], u32bit);
- void feedback();
- const u32bit FEEDBACK_SIZE;
+
+ BlockCipher* cipher;
+ SecureVector<byte> buffer, state;
+ u32bit position, feedback;
};
/*
* CFB Decryption
*/
-class BOTAN_DLL CFB_Decryption : public BlockCipherMode
+class BOTAN_DLL CFB_Decryption : public Keyed_Filter
{
public:
- CFB_Decryption(BlockCipher*, u32bit = 0);
- CFB_Decryption(BlockCipher*, const SymmetricKey&,
- const InitializationVector&, u32bit = 0);
+ std::string name() const { return cipher->name() + "/CFB"; }
+
+ 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); }
+
+ CFB_Decryption(BlockCipher* cipher, u32bit feedback = 0);
+
+ CFB_Decryption(BlockCipher* cipher,
+ const SymmetricKey& key,
+ const InitializationVector& iv,
+ u32bit feedback = 0);
private:
void write(const byte[], u32bit);
- void feedback();
- const u32bit FEEDBACK_SIZE;
+
+ BlockCipher* cipher;
+ SecureVector<byte> buffer, state;
+ u32bit position, feedback;
};
}
diff --git a/src/filters/modes/cfb/info.txt b/src/filters/modes/cfb/info.txt
index 230899a03..eb2cc69ba 100644
--- a/src/filters/modes/cfb/info.txt
+++ b/src/filters/modes/cfb/info.txt
@@ -1 +1,5 @@
define CFB
+
+<requires>
+block
+</requires>
diff --git a/src/filters/modes/cts/cts.cpp b/src/filters/modes/cts/cts.cpp
index 226a31898..3a15a1d68 100644
--- a/src/filters/modes/cts/cts.cpp
+++ b/src/filters/modes/cts/cts.cpp
@@ -12,13 +12,53 @@
namespace Botan {
/*
+* CTS Encryption Constructor
+*/
+CTS_Encryption::CTS_Encryption(BlockCipher* ciph) :
+ cipher(ciph)
+ {
+ buffer.resize(2 * cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ position = 0;
+ }
+
+/*
+* CTS Encryption Constructor
+*/
+CTS_Encryption::CTS_Encryption(BlockCipher* ciph,
+ const SymmetricKey& key,
+ const InitializationVector& iv) :
+ cipher(ciph)
+ {
+ buffer.resize(2 * cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ position = 0;
+
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*
+* Set the IV
+*/
+void CTS_Encryption::set_iv(const InitializationVector& iv)
+ {
+ if(iv.length() != state.size())
+ throw Invalid_IV_Length(name(), iv.length());
+
+ state = iv.bits_of();
+ buffer.clear();
+ position = 0;
+ }
+
+/*
* Encrypt a block
*/
void CTS_Encryption::encrypt(const byte block[])
{
- xor_buf(state, block, BLOCK_SIZE);
+ xor_buf(state, block, cipher->BLOCK_SIZE);
cipher->encrypt(state);
- send(state, BLOCK_SIZE);
+ send(state, cipher->BLOCK_SIZE);
}
/*
@@ -26,7 +66,7 @@ void CTS_Encryption::encrypt(const byte block[])
*/
void CTS_Encryption::write(const byte input[], u32bit length)
{
- u32bit copied = std::min(BUFFER_SIZE - position, length);
+ u32bit copied = std::min(buffer.size() - position, length);
buffer.copy(position, input, copied);
length -= copied;
input += copied;
@@ -35,21 +75,21 @@ void CTS_Encryption::write(const byte input[], u32bit length)
if(length == 0) return;
encrypt(buffer);
- if(length > BLOCK_SIZE)
+ if(length > cipher->BLOCK_SIZE)
{
- encrypt(buffer + BLOCK_SIZE);
- while(length > 2*BLOCK_SIZE)
+ encrypt(buffer + cipher->BLOCK_SIZE);
+ while(length > 2*cipher->BLOCK_SIZE)
{
encrypt(input);
- length -= BLOCK_SIZE;
- input += BLOCK_SIZE;
+ length -= cipher->BLOCK_SIZE;
+ input += cipher->BLOCK_SIZE;
}
position = 0;
}
else
{
- copy_mem(buffer.begin(), buffer + BLOCK_SIZE, BLOCK_SIZE);
- position = BLOCK_SIZE;
+ copy_mem(buffer.begin(), buffer + cipher->BLOCK_SIZE, cipher->BLOCK_SIZE);
+ position = cipher->BLOCK_SIZE;
}
buffer.copy(position, input, length);
position += length;
@@ -60,14 +100,56 @@ void CTS_Encryption::write(const byte input[], u32bit length)
*/
void CTS_Encryption::end_msg()
{
- if(position < BLOCK_SIZE + 1)
+ if(position < cipher->BLOCK_SIZE + 1)
throw Exception("CTS_Encryption: insufficient data to encrypt");
- xor_buf(state, buffer, BLOCK_SIZE);
+ xor_buf(state, buffer, cipher->BLOCK_SIZE);
cipher->encrypt(state);
SecureVector<byte> cn = state;
- clear_mem(buffer + position, BUFFER_SIZE - position);
- encrypt(buffer + BLOCK_SIZE);
- send(cn, position - BLOCK_SIZE);
+ clear_mem(buffer + position, buffer.size() - position);
+ encrypt(buffer + cipher->BLOCK_SIZE);
+ send(cn, position - cipher->BLOCK_SIZE);
+ }
+
+/*
+* CTS Decryption Constructor
+*/
+CTS_Decryption::CTS_Decryption(BlockCipher* ciph) :
+ cipher(ciph)
+ {
+ buffer.resize(2 * cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ temp.resize(cipher->BLOCK_SIZE);
+ position = 0;
+ }
+
+/*
+* CTS Decryption Constructor
+*/
+CTS_Decryption::CTS_Decryption(BlockCipher* ciph,
+ const SymmetricKey& key,
+ const InitializationVector& iv) :
+ cipher(ciph)
+ {
+ buffer.resize(2 * cipher->BLOCK_SIZE);
+ state.resize(cipher->BLOCK_SIZE);
+ temp.resize(cipher->BLOCK_SIZE);
+ position = 0;
+
+ set_key(key);
+ set_iv(iv);
+ }
+
+/*
+* Set the IV
+*/
+void CTS_Decryption::set_iv(const InitializationVector& iv)
+ {
+ if(iv.length() != state.size())
+ throw Invalid_IV_Length(name(), iv.length());
+
+ state = iv.bits_of();
+ buffer.clear();
+ position = 0;
}
/*
@@ -76,9 +158,9 @@ void CTS_Encryption::end_msg()
void CTS_Decryption::decrypt(const byte block[])
{
cipher->decrypt(block, temp);
- xor_buf(temp, state, BLOCK_SIZE);
- send(temp, BLOCK_SIZE);
- state.copy(block, BLOCK_SIZE);
+ xor_buf(temp, state, cipher->BLOCK_SIZE);
+ send(temp, cipher->BLOCK_SIZE);
+ state.copy(block, cipher->BLOCK_SIZE);
}
/*
@@ -86,7 +168,7 @@ void CTS_Decryption::decrypt(const byte block[])
*/
void CTS_Decryption::write(const byte input[], u32bit length)
{
- u32bit copied = std::min(BUFFER_SIZE - position, length);
+ u32bit copied = std::min(buffer.size() - position, length);
buffer.copy(position, input, copied);
length -= copied;
input += copied;
@@ -95,21 +177,21 @@ void CTS_Decryption::write(const byte input[], u32bit length)
if(length == 0) return;
decrypt(buffer);
- if(length > BLOCK_SIZE)
+ if(length > cipher->BLOCK_SIZE)
{
- decrypt(buffer + BLOCK_SIZE);
- while(length > 2*BLOCK_SIZE)
+ decrypt(buffer + cipher->BLOCK_SIZE);
+ while(length > 2*cipher->BLOCK_SIZE)
{
decrypt(input);
- length -= BLOCK_SIZE;
- input += BLOCK_SIZE;
+ length -= cipher->BLOCK_SIZE;
+ input += cipher->BLOCK_SIZE;
}
position = 0;
}
else
{
- copy_mem(buffer.begin(), buffer + BLOCK_SIZE, BLOCK_SIZE);
- position = BLOCK_SIZE;
+ copy_mem(buffer.begin(), buffer + cipher->BLOCK_SIZE, cipher->BLOCK_SIZE);
+ position = cipher->BLOCK_SIZE;
}
buffer.copy(position, input, length);
position += length;
@@ -121,14 +203,14 @@ void CTS_Decryption::write(const byte input[], u32bit length)
void CTS_Decryption::end_msg()
{
cipher->decrypt(buffer, temp);
- xor_buf(temp, buffer + BLOCK_SIZE, position - BLOCK_SIZE);
+ xor_buf(temp, buffer + cipher->BLOCK_SIZE, position - cipher->BLOCK_SIZE);
SecureVector<byte> xn = temp;
- copy_mem(buffer + position, xn + (position - BLOCK_SIZE),
- BUFFER_SIZE - position);
- cipher->decrypt(buffer + BLOCK_SIZE, temp);
- xor_buf(temp, state, BLOCK_SIZE);
- send(temp, BLOCK_SIZE);
- send(xn, position - BLOCK_SIZE);
+ copy_mem(buffer + position, xn + (position - cipher->BLOCK_SIZE),
+ buffer.size() - position);
+ cipher->decrypt(buffer + cipher->BLOCK_SIZE, temp);
+ xor_buf(temp, state, cipher->BLOCK_SIZE);
+ send(temp, cipher->BLOCK_SIZE);
+ send(xn, position - cipher->BLOCK_SIZE);
}
}
diff --git a/src/filters/modes/cts/cts.h b/src/filters/modes/cts/cts.h
index 1a2cae44e..4a7513fa0 100644
--- a/src/filters/modes/cts/cts.h
+++ b/src/filters/modes/cts/cts.h
@@ -8,51 +8,69 @@
#ifndef BOTAN_CTS_H__
#define BOTAN_CTS_H__
-#include <botan/modebase.h>
#include <botan/block_cipher.h>
+#include <botan/key_filt.h>
namespace Botan {
/*
* CTS Encryption
*/
-class BOTAN_DLL CTS_Encryption : public BlockCipherMode
+class BOTAN_DLL CTS_Encryption : public Keyed_Filter
{
public:
- CTS_Encryption(BlockCipher* ciph) :
- BlockCipherMode(ciph, "CTS", ciph->BLOCK_SIZE, 0, 2) {}
+ std::string name() const { return cipher->name() + "/CTS"; }
- CTS_Encryption(BlockCipher* ciph,
+ 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); }
+
+ CTS_Encryption(BlockCipher* cipher);
+
+ CTS_Encryption(BlockCipher* cipher,
const SymmetricKey& key,
- const InitializationVector& iv) :
- BlockCipherMode(ciph, "CTS", ciph->BLOCK_SIZE, 0, 2)
- { set_key(key); set_iv(iv); }
+ const InitializationVector& iv);
private:
void write(const byte[], u32bit);
void end_msg();
void encrypt(const byte[]);
+
+ BlockCipher* cipher;
+ SecureVector<byte> buffer, state;
+ u32bit position;
};
/*
* CTS Decryption
*/
-class BOTAN_DLL CTS_Decryption : public BlockCipherMode
+class BOTAN_DLL CTS_Decryption : public Keyed_Filter
{
public:
- CTS_Decryption(BlockCipher* ciph) :
- BlockCipherMode(ciph, "CTS", ciph->BLOCK_SIZE, 0, 2)
- { temp.resize(BLOCK_SIZE); }
+ std::string name() const { return cipher->name() + "/CTS"; }
- CTS_Decryption(BlockCipher* ciph,
+ 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); }
+
+ CTS_Decryption(BlockCipher* cipher);
+
+ CTS_Decryption(BlockCipher* cipher,
const SymmetricKey& key,
- const InitializationVector& iv) :
- BlockCipherMode(ciph, "CTS", ciph->BLOCK_SIZE, 0, 2)
- { set_key(key); set_iv(iv); temp.resize(BLOCK_SIZE); }
+ const InitializationVector& iv);
private:
void write(const byte[], u32bit);
void end_msg();
void decrypt(const byte[]);
- SecureVector<byte> temp;
+
+ BlockCipher* cipher;
+ SecureVector<byte> buffer, state, temp;
+ u32bit position;
};
}
diff --git a/src/filters/modes/cts/info.txt b/src/filters/modes/cts/info.txt
index 237f8cd97..7b590c5cb 100644
--- a/src/filters/modes/cts/info.txt
+++ b/src/filters/modes/cts/info.txt
@@ -1 +1,5 @@
define CTS
+
+<requires>
+block
+</requires>
diff --git a/src/filters/modes/eax/eax.cpp b/src/filters/modes/eax/eax.cpp
index 1187d8461..ee3b9f8e7 100644
--- a/src/filters/modes/eax/eax.cpp
+++ b/src/filters/modes/eax/eax.cpp
@@ -7,8 +7,9 @@
#include <botan/eax.h>
#include <botan/cmac.h>
-#include <botan/internal/xor_buf.h>
+#include <botan/ctr.h>
#include <botan/parsing.h>
+#include <botan/internal/xor_buf.h>
#include <algorithm>
namespace Botan {
@@ -34,20 +35,17 @@ SecureVector<byte> eax_prf(byte tag, u32bit BLOCK_SIZE,
/*
* EAX_Base Constructor
*/
-EAX_Base::EAX_Base(BlockCipher* ciph,
- u32bit tag_size) :
- TAG_SIZE(tag_size ? tag_size / 8 : ciph->BLOCK_SIZE),
- BLOCK_SIZE(ciph->BLOCK_SIZE)
+EAX_Base::EAX_Base(BlockCipher* cipher, u32bit tag_size) :
+ BLOCK_SIZE(cipher->BLOCK_SIZE),
+ TAG_SIZE(tag_size ? tag_size / 8 : BLOCK_SIZE),
+ cipher_name(cipher->name()),
+ ctr_buf(DEFAULT_BUFFERSIZE)
{
- cipher = ciph;
- mac = new CMAC(cipher->clone());
+ cmac = new CMAC(cipher->clone());
+ ctr = new CTR_BE(cipher); // takes ownership
- if(tag_size % 8 != 0 || TAG_SIZE == 0 || TAG_SIZE > mac->OUTPUT_LENGTH)
+ if(tag_size % 8 != 0 || TAG_SIZE == 0 || TAG_SIZE > cmac->OUTPUT_LENGTH)
throw Invalid_Argument(name() + ": Bad tag size " + std::to_string(tag_size));
-
- state.resize(BLOCK_SIZE);
- buffer.resize(BLOCK_SIZE);
- position = 0;
}
/*
@@ -55,9 +53,7 @@ EAX_Base::EAX_Base(BlockCipher* ciph,
*/
bool EAX_Base::valid_keylength(u32bit n) const
{
- if(!cipher->valid_keylength(n))
- return false;
- if(!mac->valid_keylength(n))
+ if(!ctr->valid_keylength(n))
return false;
return true;
}
@@ -67,9 +63,14 @@ bool EAX_Base::valid_keylength(u32bit n) const
*/
void EAX_Base::set_key(const SymmetricKey& key)
{
- cipher->set_key(key);
- mac->set_key(key);
- header_mac = eax_prf(1, BLOCK_SIZE, mac, 0, 0);
+ /*
+ * These could share the key schedule, which is one nice part of EAX,
+ * but it's much easier to ignore that here...
+ */
+ ctr->set_key(key);
+ cmac->set_key(key);
+
+ header_mac = eax_prf(1, BLOCK_SIZE, cmac, 0, 0);
}
/*
@@ -78,8 +79,8 @@ void EAX_Base::set_key(const SymmetricKey& key)
void EAX_Base::start_msg()
{
for(u32bit j = 0; j != BLOCK_SIZE - 1; ++j)
- mac->update(0);
- mac->update(2);
+ cmac->update(0);
+ cmac->update(2);
}
/*
@@ -87,9 +88,8 @@ void EAX_Base::start_msg()
*/
void EAX_Base::set_iv(const InitializationVector& iv)
{
- nonce_mac = eax_prf(0, BLOCK_SIZE, mac, iv.begin(), iv.length());
- state = nonce_mac;
- cipher->encrypt(state, buffer);
+ nonce_mac = eax_prf(0, BLOCK_SIZE, cmac, iv.begin(), iv.length());
+ ctr->set_iv(&nonce_mac[0], nonce_mac.size());
}
/*
@@ -97,7 +97,7 @@ void EAX_Base::set_iv(const InitializationVector& iv)
*/
void EAX_Base::set_header(const byte header[], u32bit length)
{
- header_mac = eax_prf(1, BLOCK_SIZE, mac, header, length);
+ header_mac = eax_prf(1, BLOCK_SIZE, cmac, header, length);
}
/*
@@ -105,19 +105,7 @@ void EAX_Base::set_header(const byte header[], u32bit length)
*/
std::string EAX_Base::name() const
{
- return (cipher->name() + "/EAX");
- }
-
-/*
-* Increment the counter and update the buffer
-*/
-void EAX_Base::increment_counter()
- {
- for(s32bit j = BLOCK_SIZE - 1; j >= 0; --j)
- if(++state[j])
- break;
- cipher->encrypt(state, buffer);
- position = 0;
+ return (cipher_name + "/EAX");
}
/*
@@ -125,32 +113,17 @@ void EAX_Base::increment_counter()
*/
void EAX_Encryption::write(const byte input[], u32bit length)
{
- u32bit copied = std::min(BLOCK_SIZE - position, length);
- xor_buf(buffer + position, input, copied);
- send(buffer + position, copied);
- mac->update(buffer + position, copied);
- input += copied;
- length -= copied;
- position += copied;
-
- if(position == BLOCK_SIZE)
- increment_counter();
-
- while(length >= BLOCK_SIZE)
+ while(length)
{
- xor_buf(buffer, input, BLOCK_SIZE);
- send(buffer, BLOCK_SIZE);
- mac->update(buffer, BLOCK_SIZE);
+ u32bit copied = std::min(length, ctr_buf.size());
- input += BLOCK_SIZE;
- length -= BLOCK_SIZE;
- increment_counter();
- }
+ ctr->cipher(input, ctr_buf, copied);
+ cmac->update(ctr_buf, copied);
- xor_buf(buffer + position, input, length);
- send(buffer + position, length);
- mac->update(buffer + position, length);
- position += length;
+ send(ctr_buf, copied);
+ input += copied;
+ length -= copied;
+ }
}
/*
@@ -158,15 +131,11 @@ void EAX_Encryption::write(const byte input[], u32bit length)
*/
void EAX_Encryption::end_msg()
{
- SecureVector<byte> data_mac = mac->final();
+ SecureVector<byte> data_mac = cmac->final();
xor_buf(data_mac, nonce_mac, data_mac.size());
xor_buf(data_mac, header_mac, data_mac.size());
send(data_mac, TAG_SIZE);
-
- state.clear();
- buffer.clear();
- position = 0;
}
}
diff --git a/src/filters/modes/eax/eax.h b/src/filters/modes/eax/eax.h
index f569f2ede..e45e29ba8 100644
--- a/src/filters/modes/eax/eax.h
+++ b/src/filters/modes/eax/eax.h
@@ -10,6 +10,7 @@
#include <botan/key_filt.h>
#include <botan/block_cipher.h>
+#include <botan/stream_cipher.h>
#include <botan/mac.h>
namespace Botan {
@@ -27,17 +28,19 @@ class BOTAN_DLL EAX_Base : public Keyed_Filter
bool valid_keylength(u32bit) const;
- ~EAX_Base() { delete cipher; delete mac; }
+ ~EAX_Base() { delete ctr; delete cmac; }
protected:
EAX_Base(BlockCipher*, u32bit);
void start_msg();
- void increment_counter();
- const u32bit TAG_SIZE, BLOCK_SIZE;
- BlockCipher* cipher;
- MessageAuthenticationCode* mac;
- SecureVector<byte> nonce_mac, header_mac, state, buffer;
- u32bit position;
+ const u32bit BLOCK_SIZE, TAG_SIZE;
+ std::string cipher_name;
+
+ StreamCipher* ctr;
+ MessageAuthenticationCode* cmac;
+
+ SecureVector<byte> nonce_mac, header_mac;
+ SecureVector<byte> ctr_buf;
};
/*
@@ -76,6 +79,7 @@ class BOTAN_DLL EAX_Decryption : public EAX_Base
void write(const byte[], u32bit);
void do_write(const byte[], u32bit);
void end_msg();
+
SecureVector<byte> queue;
u32bit queue_start, queue_end;
};
diff --git a/src/filters/modes/eax/eax_dec.cpp b/src/filters/modes/eax/eax_dec.cpp
index 24b68f3b7..f41327ffc 100644
--- a/src/filters/modes/eax/eax_dec.cpp
+++ b/src/filters/modes/eax/eax_dec.cpp
@@ -52,7 +52,6 @@ void EAX_Decryption::write(const byte input[], u32bit length)
length -= copied;
queue_end += copied;
- SecureVector<byte> block_buf(cipher->BLOCK_SIZE);
while((queue_end - queue_start) > TAG_SIZE)
{
u32bit removed = (queue_end - queue_start) - TAG_SIZE;
@@ -77,31 +76,20 @@ void EAX_Decryption::write(const byte input[], u32bit length)
*/
void EAX_Decryption::do_write(const byte input[], u32bit length)
{
- mac->update(input, length);
-
- u32bit copied = std::min(BLOCK_SIZE - position, length);
- xor_buf(buffer + position, input, copied);
- send(buffer + position, copied);
- input += copied;
- length -= copied;
- position += copied;
-
- if(position == BLOCK_SIZE)
- increment_counter();
-
- while(length >= BLOCK_SIZE)
+ while(length)
{
- xor_buf(buffer, input, BLOCK_SIZE);
- send(buffer, BLOCK_SIZE);
-
- input += BLOCK_SIZE;
- length -= BLOCK_SIZE;
- increment_counter();
+ u32bit copied = std::min(length, ctr_buf.size());
+
+ /*
+ Process same block with cmac and ctr at the same time to
+ help cache locality.
+ */
+ cmac->update(input, copied);
+ ctr->cipher(input, ctr_buf, copied);
+ send(ctr_buf, copied);
+ input += copied;
+ length -= copied;
}
-
- xor_buf(buffer + position, input, length);
- send(buffer + position, length);
- position += length;
}
/*
@@ -112,15 +100,12 @@ void EAX_Decryption::end_msg()
if((queue_end - queue_start) != TAG_SIZE)
throw Integrity_Failure(name() + ": Message authentication failure");
- SecureVector<byte> data_mac = mac->final();
+ SecureVector<byte> data_mac = cmac->final();
for(u32bit j = 0; j != TAG_SIZE; ++j)
if(queue[queue_start+j] != (data_mac[j] ^ nonce_mac[j] ^ header_mac[j]))
throw Integrity_Failure(name() + ": Message authentication failure");
- state.clear();
- buffer.clear();
- position = 0;
queue_start = queue_end = 0;
}
diff --git a/src/filters/modes/eax/info.txt b/src/filters/modes/eax/info.txt
index 4c91318d6..09d92e724 100644
--- a/src/filters/modes/eax/info.txt
+++ b/src/filters/modes/eax/info.txt
@@ -1,5 +1,7 @@
define EAX
<requires>
+block
cmac
+ctr
</requires>
diff --git a/src/filters/modes/ecb/ecb.h b/src/filters/modes/ecb/ecb.h
index ff9ea9635..2b3b3fe83 100644
--- a/src/filters/modes/ecb/ecb.h
+++ b/src/filters/modes/ecb/ecb.h
@@ -8,11 +8,9 @@
#ifndef BOTAN_ECB_H__
#define BOTAN_ECB_H__
-#include <botan/basefilt.h>
#include <botan/block_cipher.h>
#include <botan/mode_pad.h>
-
-#include <botan/modebase.h>
+#include <botan/key_filt.h>
namespace Botan {
diff --git a/src/filters/modes/ecb/info.txt b/src/filters/modes/ecb/info.txt
index a26930470..38a56040c 100644
--- a/src/filters/modes/ecb/info.txt
+++ b/src/filters/modes/ecb/info.txt
@@ -1,5 +1,6 @@
define ECB
<requires>
+block
mode_pad
</requires>
diff --git a/src/filters/modes/info.txt b/src/filters/modes/info.txt
deleted file mode 100644
index 6d27c9709..000000000
--- a/src/filters/modes/info.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-define CIPHER_MODEBASE
-
-<requires>
-block
-filters
-</requires>
diff --git a/src/filters/modes/mode_pad/mode_pad.cpp b/src/filters/modes/mode_pad/mode_pad.cpp
index 2204c28b5..94f84fa03 100644
--- a/src/filters/modes/mode_pad/mode_pad.cpp
+++ b/src/filters/modes/mode_pad/mode_pad.cpp
@@ -120,8 +120,7 @@ u32bit OneAndZeros_Padding::unpad(const byte block[], u32bit size) const
*/
bool OneAndZeros_Padding::valid_blocksize(u32bit size) const
{
- if(size) return true;
- else return false;
+ return (size > 0);
}
}
diff --git a/src/filters/modes/modebase.cpp b/src/filters/modes/modebase.cpp
deleted file mode 100644
index 59ee55a8a..000000000
--- a/src/filters/modes/modebase.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-* Block Cipher Mode
-* (C) 1999-2007 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/modebase.h>
-
-namespace Botan {
-
-/*
-* Block Cipher Mode Constructor
-*/
-BlockCipherMode::BlockCipherMode(BlockCipher* cipher_ptr,
- const std::string& cipher_mode_name,
- u32bit iv_size, u32bit iv_meth,
- u32bit buf_mult) :
- BLOCK_SIZE(cipher_ptr->BLOCK_SIZE), BUFFER_SIZE(buf_mult * BLOCK_SIZE),
- IV_METHOD(iv_meth), mode_name(cipher_mode_name)
- {
- cipher = cipher_ptr;
- buffer.resize(BUFFER_SIZE);
- state.resize(iv_size);
- position = 0;
- }
-
-/*
-* Return the name of this type
-*/
-std::string BlockCipherMode::name() const
- {
- return (cipher->name() + "/" + mode_name);
- }
-
-/*
-* Set the IV
-*/
-void BlockCipherMode::set_iv(const InitializationVector& new_iv)
- {
- if(new_iv.length() != state.size())
- throw Invalid_IV_Length(name(), new_iv.length());
-
- state = new_iv.bits_of();
- buffer.clear();
- position = 0;
-
- if(IV_METHOD == 1)
- cipher->encrypt(state, buffer);
- else if(IV_METHOD == 2)
- cipher->encrypt(state);
- }
-
-}
diff --git a/src/filters/modes/modebase.h b/src/filters/modes/modebase.h
deleted file mode 100644
index 4a15524b6..000000000
--- a/src/filters/modes/modebase.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-* Block Cipher Mode
-* (C) 1999-2007 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#ifndef BOTAN_MODEBASE_H__
-#define BOTAN_MODEBASE_H__
-
-#include <botan/key_filt.h>
-#include <botan/block_cipher.h>
-
-namespace Botan {
-
-/**
-* This class represents an abstract block cipher mode
-*/
-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:
- const u32bit BLOCK_SIZE, BUFFER_SIZE, IV_METHOD;
- const std::string mode_name;
- BlockCipher* cipher;
- SecureVector<byte> buffer, state;
- u32bit position;
- };
-
-}
-
-#endif
diff --git a/src/filters/modes/xts/info.txt b/src/filters/modes/xts/info.txt
index 9af3238f1..7327298f9 100644
--- a/src/filters/modes/xts/info.txt
+++ b/src/filters/modes/xts/info.txt
@@ -1 +1,5 @@
define XTS
+
+<requires>
+block
+</requires>
diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp
index ab74faf42..869257567 100644
--- a/src/hash/skein/skein_512.cpp
+++ b/src/hash/skein/skein_512.cpp
@@ -27,11 +27,11 @@ enum type_code {
SKEIN_OUTPUT = 63
};
-void ubi_512(u64bit H[9], u64bit T[], const byte msg[], u64bit msg_len)
+void ubi_512(u64bit H[9], u64bit T[], const byte msg[], u32bit msg_len)
{
do
{
- const u64bit to_proc = std::min<u64bit>(msg_len, 64);
+ const u32bit to_proc = std::min<u32bit>(msg_len, 64);
T[0] += to_proc;
u64bit M[8] = { 0 };
diff --git a/src/libstate/lookup.cpp b/src/libstate/lookup.cpp
index 3b49116f6..9016dbe6e 100644
--- a/src/libstate/lookup.cpp
+++ b/src/libstate/lookup.cpp
@@ -71,7 +71,7 @@ HashFunction* get_hash(const std::string& algo_spec)
bool have_hash(const std::string& algo_spec)
{
Algorithm_Factory& af = global_state().algorithm_factory();
- return af.prototype_hash_function(algo_spec);
+ return (af.prototype_hash_function(algo_spec) != 0);
}
/**
@@ -98,7 +98,7 @@ MessageAuthenticationCode* get_mac(const std::string& algo_spec)
bool have_mac(const std::string& algo_spec)
{
Algorithm_Factory& af = global_state().algorithm_factory();
- return af.prototype_mac(algo_spec);
+ return (af.prototype_mac(algo_spec) != 0);
}
/**
diff --git a/src/math/numbertheory/numthry.cpp b/src/math/numbertheory/numthry.cpp
index 42e83fa4a..760250712 100644
--- a/src/math/numbertheory/numthry.cpp
+++ b/src/math/numbertheory/numthry.cpp
@@ -76,8 +76,6 @@ u32bit miller_rabin_test_iterations(u32bit bits, bool verify)
*/
u32bit low_zero_bits(const BigInt& n)
{
- if(n.is_negative() || n.is_zero()) return 0;
-
u32bit low_zero = 0;
if(n.is_positive() && n.is_nonzero())
diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp
index 2f6bea4cd..d1fdd03b0 100644
--- a/src/selftest/selftest.cpp
+++ b/src/selftest/selftest.cpp
@@ -19,12 +19,14 @@ namespace {
*/
bool test_filter_kat(Filter* filter,
const std::string& input,
- const std::string& output)
+ const std::string& expected_output)
{
Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder);
pipe.process_msg(input);
- return (output == pipe.read_all_as_string());
+ std::string output = pipe.read_all_as_string();
+
+ return (output == expected_output);
}
}
diff --git a/src/utils/bswap.h b/src/utils/bswap.h
index 1a5349fd0..96ec4982a 100644
--- a/src/utils/bswap.h
+++ b/src/utils/bswap.h
@@ -12,6 +12,14 @@
#include <botan/types.h>
#include <botan/rotate.h>
+#if defined(BOTAN_TARGET_CPU_HAS_SSE2)
+ #include <emmintrin.h>
+#endif
+
+#if defined(BOTAN_TARGET_CPU_HAS_SSSE3)
+ #include <tmmintrin.h>
+#endif
+
namespace Botan {
/*
@@ -66,6 +74,48 @@ inline u64bit reverse_bytes(u64bit input)
#endif
}
+template<typename T>
+inline void bswap_4(T x[4])
+ {
+ x[0] = reverse_bytes(x[0]);
+ x[1] = reverse_bytes(x[1]);
+ x[2] = reverse_bytes(x[2]);
+ x[3] = reverse_bytes(x[3]);
+ }
+
+#if defined(BOTAN_TARGET_CPU_HAS_SSSE3)
+
+template<>
+inline void bswap_4(u32bit x[4])
+ {
+ const __m128i bswap_mask = _mm_set_epi8(
+ 12, 13, 14, 15,
+ 8, 9, 10, 11,
+ 4, 5, 6, 7,
+ 0, 1, 2, 3);
+
+ __m128i T = _mm_loadu_si128((const __m128i*)x);
+ T = _mm_shuffle_epi8(T, bswap_mask);
+ _mm_storeu_si128((__m128i*)x, T);
+ }
+
+#elif defined(BOTAN_TARGET_CPU_HAS_SSE2)
+
+template<>
+inline void bswap_4(u32bit x[4])
+ {
+ __m128i T = _mm_loadu_si128((const __m128i*)x);
+
+ T = _mm_shufflehi_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
+ T = _mm_shufflelo_epi16(T, _MM_SHUFFLE(2, 3, 0, 1));
+
+ T = _mm_or_si128(_mm_srli_epi16(T, 8), _mm_slli_epi16(T, 8));
+
+ _mm_storeu_si128((__m128i*)x, T);
+ }
+
+#endif
+
}
#endif
diff --git a/src/utils/loadstor.h b/src/utils/loadstor.h
index 77a6e846c..bd2acc87d 100644
--- a/src/utils/loadstor.h
+++ b/src/utils/loadstor.h
@@ -42,7 +42,9 @@ namespace Botan {
*/
template<typename T> inline byte get_byte(u32bit byte_num, T input)
{
- return (input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3));
+ return static_cast<byte>(
+ input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3)
+ );
}
/*
@@ -202,24 +204,22 @@ inline void load_le(T out[],
const byte in[],
u32bit count)
{
-#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS)
std::memcpy(out, in, sizeof(T)*count);
-#else
+
+#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
const u32bit blocks = count - (count % 4);
const u32bit left = count - blocks;
for(u32bit i = 0; i != blocks; i += 4)
- {
- out[0] = load_le<T>(in, 0);
- out[1] = load_le<T>(in, 1);
- out[2] = load_le<T>(in, 2);
- out[3] = load_le<T>(in, 3);
-
- out += 4;
- in += 4*sizeof(T);
- }
+ bswap_4(out + i);
for(u32bit i = 0; i != left; ++i)
+ out[blocks+i] = reverse_bytes(out[blocks+i]);
+#endif
+
+#else
+ for(u32bit i = 0; i != count; ++i)
out[i] = load_le<T>(in, i);
#endif
}
@@ -261,24 +261,22 @@ inline void load_be(T out[],
const byte in[],
u32bit count)
{
-#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS)
std::memcpy(out, in, sizeof(T)*count);
-#else
+
+#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
const u32bit blocks = count - (count % 4);
const u32bit left = count - blocks;
for(u32bit i = 0; i != blocks; i += 4)
- {
- out[0] = load_be<T>(in, 0);
- out[1] = load_be<T>(in, 1);
- out[2] = load_be<T>(in, 2);
- out[3] = load_be<T>(in, 3);
-
- out += 4;
- in += 4*sizeof(T);
- }
+ bswap_4(out + i);
for(u32bit i = 0; i != left; ++i)
+ out[blocks+i] = reverse_bytes(out[blocks+i]);
+#endif
+
+#else
+ for(u32bit i = 0; i != count; ++i)
out[i] = load_be<T>(in, i);
#endif
}
diff --git a/src/utils/time.cpp b/src/utils/time.cpp
index 97804813d..db8055d9f 100644
--- a/src/utils/time.cpp
+++ b/src/utils/time.cpp
@@ -9,21 +9,25 @@
#include <botan/exceptn.h>
#include <ctime>
+#if defined(BOTAN_TARGET_OS_HAS_WIN32_GET_SYSTEMTIME)
+ #include <windows.h>
+#endif
+
#if defined(BOTAN_TARGET_OS_HAS_GETTIMEOFDAY)
#include <sys/time.h>
#endif
#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME)
-#ifndef _POSIX_C_SOURCE
- #define _POSIX_C_SOURCE 199309
-#endif
+ #ifndef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 199309
+ #endif
-#include <time.h>
+ #include <time.h>
-#ifndef CLOCK_REALTIME
- #define CLOCK_REALTIME 0
-#endif
+ #ifndef CLOCK_REALTIME
+ #define CLOCK_REALTIME 0
+ #endif
#endif
@@ -64,12 +68,34 @@ calendar_point calendar_value(
{
std::tm tm = do_gmtime(std::chrono::system_clock::to_time_t(time_point));
+<<<<<<< variant A
+ std::tm tm;
+
+#if defined(BOTAN_TARGET_OS_HAS_GMTIME_S)
+ gmtime_s(&tm, &time_val); // Windows
+#elif defined(BOTAN_TARGET_OS_HAS_GMTIME_R)
+ gmtime_r(&time_val, &tm); // Unix/SUSv2
+#else
+ std::tm* tm_p = std::gmtime(&time_val);
+ if (tm_p == 0)
+ throw Encoding_Error("time_t_to_tm could not convert");
+ tm = *tm_p;
+#endif
+
+ return tm;
+>>>>>>> variant B
return calendar_point(tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec);
+####### Ancestor
+ std::tm* tm_p = std::gmtime(&time_val);
+ if (tm_p == 0)
+ throw Encoding_Error("time_t_to_tm could not convert");
+ return (*tm_p);
+======= end
}
u64bit get_nanoseconds_clock()
@@ -84,6 +110,16 @@ u64bit get_nanoseconds_clock()
::gettimeofday(&tv, 0);
return combine_timers(tv.tv_sec, tv.tv_usec, 1000000);
+#elif defined(BOTAN_TARGET_OS_HAS_WIN32_GET_SYSTEMTIME)
+
+ // Returns time since January 1, 1601 in 100-ns increments
+ ::FILETIME tv;
+ ::GetSystemTimeAsFileTime(&tv);
+ u64bit tstamp = (static_cast<u64bit>(tv.dwHighDateTime) << 32) |
+ tv.dwLowDateTime;
+
+ return (tstamp * 100); // Scale to 1 nanosecond units
+
#else
return combine_timers(std::time(0), std::clock(), CLOCKS_PER_SEC);
diff --git a/src/utils/xor_buf.h b/src/utils/xor_buf.h
index 39c4a493d..0d7d587c8 100644
--- a/src/utils/xor_buf.h
+++ b/src/utils/xor_buf.h
@@ -22,7 +22,7 @@ inline void xor_buf(byte out[], const byte in[], u32bit length)
{
while(length >= 8)
{
-#if BOTAN_UNALIGNED_MEMORY_ACCESS_OK
+#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
*reinterpret_cast<u64bit*>(out) ^= *reinterpret_cast<const u64bit*>(in);
#else
out[0] ^= in[0]; out[1] ^= in[1];
@@ -51,7 +51,7 @@ inline void xor_buf(byte out[],
{
while(length >= 8)
{
-#if BOTAN_UNALIGNED_MEMORY_ACCESS_OK
+#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
*reinterpret_cast<u64bit*>(out) =
*reinterpret_cast<const u64bit*>(in) ^
*reinterpret_cast<const u64bit*>(in2);