summaryrefslogtreecommitdiffstats
path: root/botan/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'botan/src/utils')
-rw-r--r--botan/src/utils/asm_amd64/asm_macr.h127
-rw-r--r--botan/src/utils/asm_amd64/info.txt16
-rw-r--r--botan/src/utils/asm_ia32/asm_macr.h128
-rw-r--r--botan/src/utils/asm_ia32/info.txt16
-rw-r--r--botan/src/utils/bit_ops.h91
-rw-r--r--botan/src/utils/bswap.h62
-rw-r--r--botan/src/utils/buf_comp/buf_comp.h126
-rw-r--r--botan/src/utils/buf_comp/info.txt11
-rw-r--r--botan/src/utils/charset.cpp201
-rw-r--r--botan/src/utils/charset.h44
-rw-r--r--botan/src/utils/datastor/datastor.cpp172
-rw-r--r--botan/src/utils/datastor/datastor.h61
-rw-r--r--botan/src/utils/datastor/info.txt13
-rw-r--r--botan/src/utils/exceptn.cpp62
-rw-r--r--botan/src/utils/exceptn.h197
-rw-r--r--botan/src/utils/info.txt33
-rw-r--r--botan/src/utils/loadstor.h281
-rw-r--r--botan/src/utils/mem_ops.h40
-rw-r--r--botan/src/utils/mlock.cpp55
-rw-r--r--botan/src/utils/parsing.cpp288
-rw-r--r--botan/src/utils/parsing.h41
-rw-r--r--botan/src/utils/rotate.h30
-rw-r--r--botan/src/utils/stl_util.h86
-rw-r--r--botan/src/utils/types.h42
-rw-r--r--botan/src/utils/ui.cpp36
-rw-r--r--botan/src/utils/ui.h36
-rw-r--r--botan/src/utils/util.cpp68
-rw-r--r--botan/src/utils/util.h39
-rw-r--r--botan/src/utils/version.cpp36
-rw-r--r--botan/src/utils/version.h61
-rw-r--r--botan/src/utils/xor_buf.h74
31 files changed, 2573 insertions, 0 deletions
diff --git a/botan/src/utils/asm_amd64/asm_macr.h b/botan/src/utils/asm_amd64/asm_macr.h
new file mode 100644
index 0000000..287fa3e
--- /dev/null
+++ b/botan/src/utils/asm_amd64/asm_macr.h
@@ -0,0 +1,127 @@
+/*
+* Assembly Macros
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_AMD64_ASM_MACROS_H__
+#define BOTAN_AMD64_ASM_MACROS_H__
+
+/*
+* General/Global Macros
+*/
+#define ALIGN .p2align 4,,15
+
+#define START_LISTING(FILENAME) \
+ .file #FILENAME; \
+ .text; \
+ ALIGN;
+
+#if defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
+
+/*
+* Function Definitions
+*/
+#define START_FUNCTION(func_name) \
+ ALIGN; \
+ .global func_name; \
+ .type func_name,@function; \
+func_name:
+
+#define END_FUNCTION(func_name) \
+ ret
+
+/*
+* Conditional Jumps
+*/
+#define JUMP_IF_ZERO(REG, LABEL) \
+ cmp IMM(0), REG; \
+ jz LABEL
+
+#define JUMP_IF_LT(REG, NUM, LABEL) \
+ cmp IMM(NUM), REG; \
+ jl LABEL
+
+/*
+* Register Names
+*/
+#define R0 %rax
+#define R1 %rbx
+#define R2 %rcx
+#define R2_32 %ecx
+#define R3 %rdx
+#define R3_32 %edx
+#define R4 %rsp
+#define R5 %rbp
+#define R6 %rsi
+#define R6_32 %esi
+#define R7 %rdi
+#define R8 %r8
+#define R9 %r9
+#define R9_32 %r9d
+#define R10 %r10
+#define R11 %r11
+#define R12 %r12
+#define R13 %r13
+#define R14 %r14
+#define R15 %r15
+#define R16 %r16
+
+#define ARG_1 R7
+#define ARG_2 R6
+#define ARG_2_32 R6_32
+#define ARG_3 R3
+#define ARG_3_32 R3_32
+#define ARG_4 R2
+#define ARG_4_32 R2_32
+#define ARG_5 R8
+#define ARG_6 R9
+#define ARG_6_32 R9_32
+
+#define TEMP_1 R10
+#define TEMP_2 R11
+#define TEMP_3 ARG_6
+#define TEMP_4 ARG_5
+#define TEMP_5 ARG_4
+#define TEMP_5_32 ARG_4_32
+#define TEMP_6 ARG_3
+#define TEMP_7 ARG_2
+#define TEMP_8 ARG_1
+#define TEMP_9 R0
+
+/*
+* Memory Access Operations
+*/
+#define ARRAY8(REG, NUM) 8*(NUM)(REG)
+#define ARRAY4(REG, NUM) 4*(NUM)(REG)
+
+#define ASSIGN(TO, FROM) mov FROM, TO
+
+/*
+* ALU Operations
+*/
+#define IMM(VAL) $VAL
+
+#define ADD(TO, FROM) add FROM, TO
+#define ADD_LAST_CARRY(REG) adc IMM(0), REG
+#define ADD_IMM(TO, NUM) ADD(TO, IMM(NUM))
+#define ADD_W_CARRY(TO1, TO2, FROM) add FROM, TO1; adc IMM(0), TO2;
+#define SUB_IMM(TO, NUM) sub IMM(NUM), TO
+#define MUL(REG) mul REG
+
+#define XOR(TO, FROM) xor FROM, TO
+#define AND(TO, FROM) and FROM, TO
+#define OR(TO, FROM) or FROM, TO
+#define NOT(REG) not REG
+#define ZEROIZE(REG) XOR(REG, REG)
+
+#define RETURN_VALUE_IS(V) ASSIGN(%rax, V)
+
+#define ROTL_IMM(REG, NUM) rol IMM(NUM), REG
+#define ROTR_IMM(REG, NUM) ror IMM(NUM), REG
+#define ADD3_IMM(TO, FROM, NUM) lea NUM(TO,FROM,1), TO
+
+#endif
diff --git a/botan/src/utils/asm_amd64/info.txt b/botan/src/utils/asm_amd64/info.txt
new file mode 100644
index 0000000..19035b5
--- /dev/null
+++ b/botan/src/utils/asm_amd64/info.txt
@@ -0,0 +1,16 @@
+realname "Assembler Macros (x86-64)"
+
+load_on dep
+
+<add>
+asm_macr.h
+</add>
+
+<arch>
+amd64
+</arch>
+
+<cc>
+gcc
+icc
+</cc>
diff --git a/botan/src/utils/asm_ia32/asm_macr.h b/botan/src/utils/asm_ia32/asm_macr.h
new file mode 100644
index 0000000..2ea6951
--- /dev/null
+++ b/botan/src/utils/asm_ia32/asm_macr.h
@@ -0,0 +1,128 @@
+/*
+* Assembly Macros
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_IA32_ASM_MACROS_H__
+#define BOTAN_IA32_ASM_MACROS_H__
+
+/*
+* General/Global Macros
+*/
+#define ALIGN .p2align 4,,15
+
+#define START_LISTING(FILENAME) \
+ .file #FILENAME; \
+ .text; \
+ ALIGN;
+
+#if defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
+
+/*
+* Function Definitions
+*/
+#define START_FUNCTION(func_name) \
+ ALIGN; \
+ .global func_name; \
+ .type func_name,@function; \
+func_name:
+
+#define END_FUNCTION(func_name) \
+ ret
+
+/*
+* Loop Control
+*/
+#define START_LOOP(LABEL) \
+ ALIGN; \
+ LABEL##_LOOP:
+
+#define LOOP_UNTIL_EQ(REG, NUM, LABEL) \
+ cmpl IMM(NUM), REG; \
+ jne LABEL##_LOOP
+
+#define LOOP_UNTIL_LT(REG, NUM, LABEL) \
+ cmpl IMM(NUM), REG; \
+ jge LABEL##_LOOP
+
+/*
+ Conditional Jumps
+*/
+#define JUMP_IF_ZERO(REG, LABEL) \
+ cmpl IMM(0), REG; \
+ jz LABEL
+
+#define JUMP_IF_LT(REG, NUM, LABEL) \
+ cmpl IMM(NUM), REG; \
+ jl LABEL
+
+/*
+* Register Names
+*/
+#define EAX %eax
+#define EBX %ebx
+#define ECX %ecx
+#define EDX %edx
+#define EBP %ebp
+#define EDI %edi
+#define ESI %esi
+#define ESP %esp
+
+/*
+* Memory Access Operations
+*/
+#define ARRAY1(REG, NUM) (NUM)(REG)
+#define ARRAY4(REG, NUM) 4*(NUM)(REG)
+#define ARRAY4_INDIRECT(BASE, OFFSET, NUM) 4*(NUM)(BASE,OFFSET,4)
+#define ARG(NUM) 4*(PUSHED) + ARRAY4(ESP, NUM)
+
+#define ASSIGN(TO, FROM) movl FROM, TO
+#define ASSIGN_BYTE(TO, FROM) movzbl FROM, TO
+
+#define PUSH(REG) pushl REG
+#define POP(REG) popl REG
+
+#define SPILL_REGS() \
+ PUSH(EBP) ; \
+ PUSH(EDI) ; \
+ PUSH(ESI) ; \
+ PUSH(EBX)
+
+#define RESTORE_REGS() \
+ POP(EBX) ; \
+ POP(ESI) ; \
+ POP(EDI) ; \
+ POP(EBP)
+
+/*
+* ALU Operations
+*/
+#define IMM(VAL) $VAL
+
+#define ADD(TO, FROM) addl FROM, TO
+#define ADD_IMM(TO, NUM) ADD(TO, IMM(NUM))
+#define ADD_W_CARRY(TO1, TO2, FROM) addl FROM, TO1; adcl IMM(0), TO2;
+#define SUB_IMM(TO, NUM) subl IMM(NUM), TO
+#define ADD2_IMM(TO, FROM, NUM) leal NUM(FROM), TO
+#define ADD3_IMM(TO, FROM, NUM) leal NUM(TO,FROM,1), TO
+#define MUL(REG) mull REG
+
+#define SHL_IMM(REG, SHIFT) shll IMM(SHIFT), REG
+#define SHR_IMM(REG, SHIFT) shrl IMM(SHIFT), REG
+#define SHL2_3(TO, FROM) leal 0(,FROM,8), TO
+
+#define XOR(TO, FROM) xorl FROM, TO
+#define AND(TO, FROM) andl FROM, TO
+#define OR(TO, FROM) orl FROM, TO
+#define NOT(REG) notl REG
+#define ZEROIZE(REG) XOR(REG, REG)
+
+#define ROTL_IMM(REG, NUM) roll IMM(NUM), REG
+#define ROTR_IMM(REG, NUM) rorl IMM(NUM), REG
+#define BSWAP(REG) bswapl REG
+
+#endif
diff --git a/botan/src/utils/asm_ia32/info.txt b/botan/src/utils/asm_ia32/info.txt
new file mode 100644
index 0000000..4340c35
--- /dev/null
+++ b/botan/src/utils/asm_ia32/info.txt
@@ -0,0 +1,16 @@
+realname "Assembler Macros (IA-32)"
+
+load_on dep
+
+<add>
+asm_macr.h
+</add>
+
+<arch>
+ia32
+</arch>
+
+<cc>
+gcc
+icc
+</cc>
diff --git a/botan/src/utils/bit_ops.h b/botan/src/utils/bit_ops.h
new file mode 100644
index 0000000..c02ec53
--- /dev/null
+++ b/botan/src/utils/bit_ops.h
@@ -0,0 +1,91 @@
+/*
+* Bit/Word Operations
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_BIT_OPS_H__
+#define BOTAN_BIT_OPS_H__
+
+#include <botan/types.h>
+
+namespace Botan {
+
+/*
+* Return true iff arg is 2**n for some n > 0
+* T should be an unsigned integer type
+*/
+template<typename T>
+inline bool power_of_2(T arg)
+ {
+ return ((arg != 0 && arg != 1) && ((arg & (arg-1)) == 0));
+ }
+
+/*
+* Return the index of the highest set bit
+* T is an unsigned integer type
+*/
+template<typename T>
+inline u32bit high_bit(T n)
+ {
+ for(u32bit i = 8*sizeof(T); i > 0; --i)
+ if((n >> (i - 1)) & 0x01)
+ return i;
+ return 0;
+ }
+
+/*
+* Return the index of the lowest set bit
+*/
+template<typename T>
+inline u32bit low_bit(T n)
+ {
+ for(u32bit i = 0; i != 8*sizeof(T); ++i)
+ if((n >> i) & 0x01)
+ return (i + 1);
+ return 0;
+ }
+
+/*
+* Return the number of significant bytes in n
+*/
+template<typename T>
+inline u32bit significant_bytes(T n)
+ {
+ for(u32bit j = 0; j != sizeof(T); ++j)
+ if(get_byte(j, n))
+ return sizeof(T)-j;
+ return 0;
+ }
+
+/*
+* Return the Hamming weight of n
+*/
+template<typename T>
+inline u32bit hamming_weight(T n)
+ {
+ const byte NIBBLE_WEIGHTS[] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+
+ u32bit weight = 0;
+ for(u32bit i = 0; i != 2*sizeof(T); ++i)
+ weight += NIBBLE_WEIGHTS[(n >> (4*i)) & 0x0F];
+ return weight;
+ }
+
+/*
+* Count the trailing zero bits in n
+*/
+template<typename T>
+inline u32bit ctz(T n)
+ {
+ for(u32bit i = 0; i != 8*sizeof(T); ++i)
+ if((n >> i) & 0x01)
+ return i;
+ return 8*sizeof(T);
+ }
+
+}
+
+#endif
diff --git a/botan/src/utils/bswap.h b/botan/src/utils/bswap.h
new file mode 100644
index 0000000..ec1e814
--- /dev/null
+++ b/botan/src/utils/bswap.h
@@ -0,0 +1,62 @@
+/*
+* Byte Swapping Operations
+* (C) 1999-2008 Jack Lloyd
+* (C) 2007 Yves Jerschow
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_BYTE_SWAP_H__
+#define BOTAN_BYTE_SWAP_H__
+
+#include <botan/types.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+/*
+* Byte Swapping Functions
+*/
+inline u16bit reverse_bytes(u16bit input)
+ {
+ return rotate_left(input, 8);
+ }
+
+inline u32bit reverse_bytes(u32bit input)
+ {
+#if BOTAN_USE_GCC_INLINE_ASM && \
+ (defined(BOTAN_TARGET_ARCH_IS_IA32) || defined(BOTAN_TARGET_ARCH_IS_AMD64))
+
+ /* GCC-style inline assembly for x86 or x86-64 */
+ asm("bswapl %0" : "=r" (input) : "0" (input));
+ return input;
+
+#elif defined(_MSC_VER) && defined(BOTAN_TARGET_ARCH_IS_IA32)
+ /* Visual C++ inline asm for 32-bit x86, by Yves Jerschow */
+ __asm mov eax, input;
+ __asm bswap eax;
+
+#else
+ /* Generic implementation */
+ input = ((input & 0xFF00FF00) >> 8) | ((input & 0x00FF00FF) << 8);
+ return rotate_left(input, 16);
+#endif
+ }
+
+inline u64bit reverse_bytes(u64bit input)
+ {
+#if BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_ARCH_IS_AMD64)
+ asm("bswapq %0" : "=r" (input) : "0" (input));
+ return input;
+#else
+ u32bit hi = ((input >> 40) & 0x00FF00FF) | ((input >> 24) & 0xFF00FF00);
+ u32bit lo = ((input & 0xFF00FF00) >> 8) | ((input & 0x00FF00FF) << 8);
+ hi = (hi << 16) | (hi >> 16);
+ lo = (lo << 16) | (lo >> 16);
+ return (static_cast<u64bit>(lo) << 32) | hi;
+#endif
+ }
+
+}
+
+#endif
diff --git a/botan/src/utils/buf_comp/buf_comp.h b/botan/src/utils/buf_comp/buf_comp.h
new file mode 100644
index 0000000..3f1e90b
--- /dev/null
+++ b/botan/src/utils/buf_comp/buf_comp.h
@@ -0,0 +1,126 @@
+/**
+* BufferedComputation
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_BUFFERED_COMPUTATION_H__
+#define BOTAN_BUFFERED_COMPUTATION_H__
+
+#include <botan/secmem.h>
+
+namespace Botan {
+
+/**
+* This class represents any kind of computation which
+* uses an internal state,
+* such as hash functions.
+*/
+class BOTAN_DLL BufferedComputation
+ {
+ public:
+
+ /**
+ * The length of the output of this function in bytes.
+ */
+ const u32bit OUTPUT_LENGTH;
+
+ /**
+ * Add new input to process.
+ * @param in the input to process as a byte array
+ * @param the length of the byte array
+ */
+ void update(const byte in[], u32bit length) { add_data(in, length); }
+
+ /**
+ * Add new input to process.
+ * @param in the input to process as a MemoryRegion
+ */
+ void update(const MemoryRegion<byte>& in) { add_data(in, in.size()); }
+
+ /**
+ * Add new input to process.
+ * @param str the input to process as a std::string. Will be interpreted
+ * as a byte array based on
+ * the strings encoding.
+ */
+ void update(const std::string& str)
+ {
+ add_data(reinterpret_cast<const byte*>(str.data()), str.size());
+ }
+
+ /**
+ * Process a single byte.
+ * @param in the byte to process
+ */
+ void update(byte in) { add_data(&in, 1); }
+
+ /**
+ * Complete the computation and retrieve the
+ * final result.
+ * @param out The byte array to be filled with the result.
+ * Must be of length OUTPUT_LENGTH.
+ */
+ void final(byte out[]) { final_result(out); }
+
+ /**
+ * Complete the computation and retrieve the
+ * final result.
+ * @return a SecureVector holding the result
+ */
+ SecureVector<byte> final()
+ {
+ SecureVector<byte> output(OUTPUT_LENGTH);
+ final_result(output);
+ return output;
+ }
+
+ /**
+ * Update and finalize computation. Does the same as calling update()
+ * and final() consecutively.
+ * @param in the input to process as a byte array
+ * @param length the length of the byte array
+ * @result the result of the call to final()
+ */
+ SecureVector<byte> process(const byte in[], u32bit length)
+ {
+ add_data(in, length);
+ return final();
+ }
+
+ /**
+ * Update and finalize computation. Does the same as calling update()
+ * and final() consecutively.
+ * @param in the input to process
+ * @result the result of the call to final()
+ */
+ SecureVector<byte> process(const MemoryRegion<byte>& in)
+ {
+ add_data(in, in.size());
+ return final();
+ }
+
+ /**
+ * Update and finalize computation. Does the same as calling update()
+ * and final() consecutively.
+ * @param in the input to process as a string
+ * @result the result of the call to final()
+ */
+ SecureVector<byte> process(const std::string& in)
+ {
+ update(in);
+ return final();
+ }
+
+ BufferedComputation(u32bit out_len) : OUTPUT_LENGTH(out_len) {}
+ virtual ~BufferedComputation() {}
+ private:
+ BufferedComputation& operator=(const BufferedComputation&);
+ virtual void add_data(const byte[], u32bit) = 0;
+ virtual void final_result(byte[]) = 0;
+ };
+
+}
+
+#endif
diff --git a/botan/src/utils/buf_comp/info.txt b/botan/src/utils/buf_comp/info.txt
new file mode 100644
index 0000000..bcbbc23
--- /dev/null
+++ b/botan/src/utils/buf_comp/info.txt
@@ -0,0 +1,11 @@
+realname "Buffered Computation"
+
+load_on auto
+
+<add>
+buf_comp.h
+</add>
+
+<requires>
+alloc
+</requires>
diff --git a/botan/src/utils/charset.cpp b/botan/src/utils/charset.cpp
new file mode 100644
index 0000000..53125ca
--- /dev/null
+++ b/botan/src/utils/charset.cpp
@@ -0,0 +1,201 @@
+/*
+* Character Set Handling
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/charset.h>
+#include <botan/parsing.h>
+#include <botan/exceptn.h>
+#include <cctype>
+
+namespace Botan {
+
+namespace Charset {
+
+namespace {
+
+/*
+* Convert from UCS-2 to ISO 8859-1
+*/
+std::string ucs2_to_latin1(const std::string& ucs2)
+ {
+ if(ucs2.size() % 2 == 1)
+ throw Decoding_Error("UCS-2 string has an odd number of bytes");
+
+ std::string latin1;
+
+ for(u32bit j = 0; j != ucs2.size(); j += 2)
+ {
+ const byte c1 = ucs2[j];
+ const byte c2 = ucs2[j+1];
+
+ if(c1 != 0)
+ throw Decoding_Error("UCS-2 has non-Latin1 characters");
+
+ latin1 += static_cast<char>(c2);
+ }
+
+ return latin1;
+ }
+
+/*
+* Convert from UTF-8 to ISO 8859-1
+*/
+std::string utf8_to_latin1(const std::string& utf8)
+ {
+ std::string iso8859;
+
+ u32bit position = 0;
+ while(position != utf8.size())
+ {
+ const byte c1 = static_cast<byte>(utf8[position++]);
+
+ if(c1 <= 0x7F)
+ iso8859 += static_cast<char>(c1);
+ else if(c1 >= 0xC0 && c1 <= 0xC7)
+ {
+ if(position == utf8.size())
+ throw Decoding_Error("UTF-8: sequence truncated");
+
+ const byte c2 = static_cast<byte>(utf8[position++]);
+ const byte iso_char = ((c1 & 0x07) << 6) | (c2 & 0x3F);
+
+ if(iso_char <= 0x7F)
+ throw Decoding_Error("UTF-8: sequence longer than needed");
+
+ iso8859 += static_cast<char>(iso_char);
+ }
+ else
+ throw Decoding_Error("UTF-8: Unicode chars not in Latin1 used");
+ }
+
+ return iso8859;
+ }
+
+/*
+* Convert from ISO 8859-1 to UTF-8
+*/
+std::string latin1_to_utf8(const std::string& iso8859)
+ {
+ std::string utf8;
+ for(u32bit j = 0; j != iso8859.size(); ++j)
+ {
+ const byte c = static_cast<byte>(iso8859[j]);
+
+ if(c <= 0x7F)
+ utf8 += static_cast<char>(c);
+ else
+ {
+ utf8 += static_cast<char>((0xC0 | (c >> 6)));
+ utf8 += static_cast<char>((0x80 | (c & 0x3F)));
+ }
+ }
+ return utf8;
+ }
+
+}
+
+/*
+* Perform character set transcoding
+*/
+std::string transcode(const std::string& str,
+ Character_Set to, Character_Set from)
+ {
+ if(to == LOCAL_CHARSET)
+ to = LATIN1_CHARSET;
+ if(from == LOCAL_CHARSET)
+ from = LATIN1_CHARSET;
+
+ if(to == from)
+ return str;
+
+ if(from == LATIN1_CHARSET && to == UTF8_CHARSET)
+ return latin1_to_utf8(str);
+ if(from == UTF8_CHARSET && to == LATIN1_CHARSET)
+ return utf8_to_latin1(str);
+ if(from == UCS2_CHARSET && to == LATIN1_CHARSET)
+ return ucs2_to_latin1(str);
+
+ throw Invalid_Argument("Unknown transcoding operation from " +
+ to_string(from) + " to " + to_string(to));
+ }
+
+/*
+* Check if a character represents a digit
+*/
+bool is_digit(char c)
+ {
+ if(c == '0' || c == '1' || c == '2' || c == '3' || c == '4' ||
+ c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
+ return true;
+ return false;
+ }
+
+/*
+* Check if a character represents whitespace
+*/
+bool is_space(char c)
+ {
+ if(c == ' ' || c == '\t' || c == '\n' || c == '\r')
+ return true;
+ return false;
+ }
+
+/*
+* Convert a character to a digit
+*/
+byte char2digit(char c)
+ {
+ switch(c)
+ {
+ case '0': return 0;
+ case '1': return 1;
+ case '2': return 2;
+ case '3': return 3;
+ case '4': return 4;
+ case '5': return 5;
+ case '6': return 6;
+ case '7': return 7;
+ case '8': return 8;
+ case '9': return 9;
+ }
+
+ throw Invalid_Argument("char2digit: Input is not a digit character");
+ }
+
+/*
+* Convert a digit to a character
+*/
+char digit2char(byte b)
+ {
+ switch(b)
+ {
+ case 0: return '0';
+ case 1: return '1';
+ case 2: return '2';
+ case 3: return '3';
+ case 4: return '4';
+ case 5: return '5';
+ case 6: return '6';
+ case 7: return '7';
+ case 8: return '8';
+ case 9: return '9';
+ }
+
+ throw Invalid_Argument("digit2char: Input is not a digit");
+ }
+
+/*
+* Case-insensitive character comparison
+*/
+bool caseless_cmp(char a, char b)
+ {
+ return (std::tolower(static_cast<unsigned char>(a)) ==
+ std::tolower(static_cast<unsigned char>(b)));
+ }
+
+}
+
+}
diff --git a/botan/src/utils/charset.h b/botan/src/utils/charset.h
new file mode 100644
index 0000000..eebb199
--- /dev/null
+++ b/botan/src/utils/charset.h
@@ -0,0 +1,44 @@
+/*
+* Character Set Handling
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_CHARSET_H__
+#define BOTAN_CHARSET_H__
+
+#include <botan/types.h>
+#include <string>
+
+namespace Botan {
+
+/**
+* The different charsets (nominally) supported by Botan.
+*/
+enum Character_Set {
+ LOCAL_CHARSET,
+ UCS2_CHARSET,
+ UTF8_CHARSET,
+ LATIN1_CHARSET
+};
+
+namespace Charset {
+
+/*
+* Character Set Handling
+*/
+std::string transcode(const std::string&, Character_Set, Character_Set);
+
+bool is_digit(char);
+bool is_space(char);
+bool caseless_cmp(char, char);
+
+byte char2digit(char);
+char digit2char(byte);
+
+}
+
+}
+
+#endif
diff --git a/botan/src/utils/datastor/datastor.cpp b/botan/src/utils/datastor/datastor.cpp
new file mode 100644
index 0000000..129dad9
--- /dev/null
+++ b/botan/src/utils/datastor/datastor.cpp
@@ -0,0 +1,172 @@
+/*
+* Data Store
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/datastor.h>
+#include <botan/exceptn.h>
+#include <botan/parsing.h>
+#include <botan/stl_util.h>
+#include <botan/filters.h>
+
+namespace Botan {
+
+/*
+* Default Matcher transform operation (identity)
+*/
+std::pair<std::string, std::string>
+Data_Store::Matcher::transform(const std::string& key,
+ const std::string& value) const
+ {
+ return std::make_pair(key, value);
+ }
+
+/*
+* Data_Store Equality Comparison
+*/
+bool Data_Store::operator==(const Data_Store& other) const
+ {
+ return (contents == other.contents);
+ }
+
+/*
+* Check if this key has at least one value
+*/
+bool Data_Store::has_value(const std::string& key) const
+ {
+ return (contents.lower_bound(key) != contents.end());
+ }
+
+/*
+* Search based on an arbitrary predicate
+*/
+std::multimap<std::string, std::string>
+Data_Store::search_with(const Matcher& matcher) const
+ {
+ std::multimap<std::string, std::string> out;
+
+ std::multimap<std::string, std::string>::const_iterator i =
+ contents.begin();
+
+ while(i != contents.end())
+ {
+ if(matcher(i->first, i->second))
+ out.insert(matcher.transform(i->first, i->second));
+ ++i;
+ }
+
+ return out;
+ }
+
+/*
+* Search based on key equality
+*/
+std::vector<std::string> Data_Store::get(const std::string& looking_for) const
+ {
+ typedef std::multimap<std::string, std::string>::const_iterator iter;
+
+ std::pair<iter, iter> range = contents.equal_range(looking_for);
+
+ std::vector<std::string> out;
+ for(iter i = range.first; i != range.second; ++i)
+ out.push_back(i->second);
+ return out;
+ }
+
+/*
+* Get a single atom
+*/
+std::string Data_Store::get1(const std::string& key) const
+ {
+ std::vector<std::string> vals = get(key);
+
+ if(vals.empty())
+ throw Invalid_State("Data_Store::get1: Not values for " + key);
+ if(vals.size() > 1)
+ throw Invalid_State("Data_Store::get1: More than one value for " + key);
+
+ return vals[0];
+ }
+
+/*
+* Get a single MemoryVector atom
+*/
+MemoryVector<byte>
+Data_Store::get1_memvec(const std::string& key) const
+ {
+ std::vector<std::string> vals = get(key);
+
+ if(vals.size() > 1)
+ throw Invalid_State("Data_Store::get1_memvec: Multiple values for " +
+ key);
+
+ if(vals.empty())
+ return MemoryVector<byte>();
+
+ Pipe pipe(new Hex_Decoder(FULL_CHECK));
+ pipe.start_msg();
+ if(vals.size())
+ pipe.write(vals[0]);
+ pipe.end_msg();
+ return pipe.read_all();
+ }
+
+/*
+* Get a single u32bit atom
+*/
+u32bit Data_Store::get1_u32bit(const std::string& key,
+ u32bit default_val) const
+ {
+ std::vector<std::string> vals = get(key);
+
+ if(vals.empty())
+ return default_val;
+ else if(vals.size() > 1)
+ throw Invalid_State("Data_Store::get1_u32bit: Multiple values for " +
+ key);
+
+ return to_u32bit(vals[0]);
+ }
+
+/*
+* Insert a single key and value
+*/
+void Data_Store::add(const std::string& key, const std::string& val)
+ {
+ multimap_insert(contents, key, val);
+ }
+
+/*
+* Insert a single key and value
+*/
+void Data_Store::add(const std::string& key, u32bit val)
+ {
+ add(key, to_string(val));
+ }
+
+/*
+* Insert a single key and value
+*/
+void Data_Store::add(const std::string& key, const MemoryRegion<byte>& val)
+ {
+ Pipe pipe(new Hex_Encoder);
+ pipe.process_msg(val);
+ add(key, pipe.read_all_as_string());
+ }
+
+/*
+* Insert a mapping of key/value pairs
+*/
+void Data_Store::add(const std::multimap<std::string, std::string>& in)
+ {
+ std::multimap<std::string, std::string>::const_iterator i = in.begin();
+ while(i != in.end())
+ {
+ contents.insert(*i);
+ ++i;
+ }
+ }
+
+}
diff --git a/botan/src/utils/datastor/datastor.h b/botan/src/utils/datastor/datastor.h
new file mode 100644
index 0000000..7ee626f
--- /dev/null
+++ b/botan/src/utils/datastor/datastor.h
@@ -0,0 +1,61 @@
+/*
+* Data Store
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_DATA_STORE_H__
+#define BOTAN_DATA_STORE_H__
+
+#include <botan/secmem.h>
+#include <utility>
+#include <string>
+#include <vector>
+#include <map>
+
+namespace Botan {
+
+/**
+* Data Store
+*/
+class BOTAN_DLL Data_Store
+ {
+ public:
+ class BOTAN_DLL Matcher
+ {
+ public:
+ virtual bool operator()(const std::string&,
+ const std::string&) const = 0;
+
+ virtual std::pair<std::string, std::string>
+ transform(const std::string&, const std::string&) const;
+
+ virtual ~Matcher() {}
+ };
+
+ bool operator==(const Data_Store&) const;
+
+ std::multimap<std::string, std::string>
+ search_with(const Matcher&) const;
+
+ std::vector<std::string> get(const std::string&) const;
+
+ std::string get1(const std::string&) const;
+
+ MemoryVector<byte> get1_memvec(const std::string&) const;
+ u32bit get1_u32bit(const std::string&, u32bit = 0) const;
+
+ bool has_value(const std::string&) const;
+
+ void add(const std::multimap<std::string, std::string>&);
+ void add(const std::string&, const std::string&);
+ void add(const std::string&, u32bit);
+ void add(const std::string&, const MemoryRegion<byte>&);
+ private:
+ std::multimap<std::string, std::string> contents;
+ };
+
+}
+
+#endif
diff --git a/botan/src/utils/datastor/info.txt b/botan/src/utils/datastor/info.txt
new file mode 100644
index 0000000..8c38a3a
--- /dev/null
+++ b/botan/src/utils/datastor/info.txt
@@ -0,0 +1,13 @@
+realname "Datastore"
+
+load_on auto
+
+<add>
+datastor.cpp
+datastor.h
+</add>
+
+<requires>
+alloc
+filters
+</requires>
diff --git a/botan/src/utils/exceptn.cpp b/botan/src/utils/exceptn.cpp
new file mode 100644
index 0000000..753d634
--- /dev/null
+++ b/botan/src/utils/exceptn.cpp
@@ -0,0 +1,62 @@
+/*
+* Exceptions
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/exceptn.h>
+#include <botan/parsing.h>
+
+namespace Botan {
+
+/*
+* Constructor for Invalid_Key_Length
+*/
+Invalid_Key_Length::Invalid_Key_Length(const std::string& name, u32bit length)
+ {
+ set_msg(name + " cannot accept a key of length " + to_string(length));
+ }
+
+/*
+* Constructor for Invalid_Block_Size
+*/
+Invalid_Block_Size::Invalid_Block_Size(const std::string& mode,
+ const std::string& pad)
+ {
+ set_msg("Padding method " + pad + " cannot be used with " + mode);
+ }
+
+/*
+* Constructor for Invalid_IV_Length
+*/
+Invalid_IV_Length::Invalid_IV_Length(const std::string& mode, u32bit bad_len)
+ {
+ set_msg("IV length " + to_string(bad_len) + " is invalid for " + mode);
+ }
+
+/*
+* Constructor for Algorithm_Not_Found
+*/
+Algorithm_Not_Found::Algorithm_Not_Found(const std::string& name)
+ {
+ set_msg("Could not find any algorithm named \"" + name + "\"");
+ }
+
+/*
+* Constructor for Invalid_Algorithm_Name
+*/
+Invalid_Algorithm_Name::Invalid_Algorithm_Name(const std::string& name)
+ {
+ set_msg("Invalid algorithm name: " + name);
+ }
+
+/*
+* Constructor for Config_Error
+*/
+Config_Error::Config_Error(const std::string& err, u32bit line)
+ {
+ set_msg("Config error at line " + to_string(line) + ": " + err);
+ }
+
+}
diff --git a/botan/src/utils/exceptn.h b/botan/src/utils/exceptn.h
new file mode 100644
index 0000000..a55d842
--- /dev/null
+++ b/botan/src/utils/exceptn.h
@@ -0,0 +1,197 @@
+/*
+* Exceptions
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_EXCEPTION_H__
+#define BOTAN_EXCEPTION_H__
+
+#include <botan/types.h>
+#include <exception>
+#include <string>
+
+namespace Botan {
+
+/*
+* Exception Base Class
+*/
+class BOTAN_DLL Exception : public std::exception
+ {
+ public:
+ const char* what() const throw() { return msg.c_str(); }
+ Exception(const std::string& m = "Unknown error") { set_msg(m); }
+ virtual ~Exception() throw() {}
+ protected:
+ void set_msg(const std::string& m) { msg = "Botan: " + m; }
+ private:
+ std::string msg;
+ };
+
+/*
+* Invalid_Argument Exception
+*/
+struct BOTAN_DLL Invalid_Argument : public Exception
+ {
+ Invalid_Argument(const std::string& err = "") : Exception(err) {}
+ };
+
+/*
+* Invalid_Key_Length Exception
+*/
+struct BOTAN_DLL Invalid_Key_Length : public Invalid_Argument
+ {
+ Invalid_Key_Length(const std::string&, u32bit);
+ };
+
+/*
+* Invalid_Block_Size Exception
+*/
+struct BOTAN_DLL Invalid_Block_Size : public Invalid_Argument
+ {
+ Invalid_Block_Size(const std::string&, const std::string&);
+ };
+
+/*
+* Invalid_IV_Length Exception
+*/
+struct BOTAN_DLL Invalid_IV_Length : public Invalid_Argument
+ {
+ Invalid_IV_Length(const std::string&, u32bit);
+ };
+
+/*
+* Invalid_State Exception
+*/
+struct BOTAN_DLL Invalid_State : public Exception
+ {
+ Invalid_State(const std::string& err) : Exception(err) {}
+ };
+
+/*
+* PRNG_Unseeded Exception
+*/
+struct BOTAN_DLL PRNG_Unseeded : public Invalid_State
+ {
+ PRNG_Unseeded(const std::string& algo) :
+ Invalid_State("PRNG not seeded: " + algo) {}
+ };
+
+/*
+* Policy_Violation Exception
+*/
+struct BOTAN_DLL Policy_Violation : public Invalid_State
+ {
+ Policy_Violation(const std::string& err) :
+ Invalid_State("Policy violation: " + err) {}
+ };
+
+/*
+* Lookup_Error Exception
+*/
+struct BOTAN_DLL Lookup_Error : public Exception
+ {
+ Lookup_Error(const std::string& err) : Exception(err) {}
+ };
+
+/*
+* Algorithm_Not_Found Exception
+*/
+struct BOTAN_DLL Algorithm_Not_Found : public Exception
+ {
+ Algorithm_Not_Found(const std::string&);
+ };
+
+/*
+* Format_Error Exception
+*/
+struct BOTAN_DLL Format_Error : public Exception
+ {
+ Format_Error(const std::string& err = "") : Exception(err) {}
+ };
+
+/*
+* Invalid_Algorithm_Name Exception
+*/
+struct BOTAN_DLL Invalid_Algorithm_Name : public Format_Error
+ {
+ Invalid_Algorithm_Name(const std::string&);
+ };
+
+/*
+* Encoding_Error Exception
+*/
+struct BOTAN_DLL Encoding_Error : public Format_Error
+ {
+ Encoding_Error(const std::string& name) :
+ Format_Error("Encoding error: " + name) {}
+ };
+
+/*
+* Decoding_Error Exception
+*/
+struct BOTAN_DLL Decoding_Error : public Format_Error
+ {
+ Decoding_Error(const std::string& name) :
+ Format_Error("Decoding error: " + name) {}
+ };
+
+/*
+* Invalid_OID Exception
+*/
+struct BOTAN_DLL Invalid_OID : public Decoding_Error
+ {
+ Invalid_OID(const std::string& oid) :
+ Decoding_Error("Invalid ASN.1 OID: " + oid) {}
+ };
+
+/*
+* Stream_IO_Error Exception
+*/
+struct BOTAN_DLL Stream_IO_Error : public Exception
+ {
+ Stream_IO_Error(const std::string& err) :
+ Exception("I/O error: " + err) {}
+ };
+
+/*
+* Configuration Error Exception
+*/
+struct BOTAN_DLL Config_Error : public Format_Error
+ {
+ Config_Error(const std::string& err) :
+ Format_Error("Config error: " + err) {}
+ Config_Error(const std::string&, u32bit);
+ };
+
+/*
+* Integrity Failure Exception
+*/
+struct BOTAN_DLL Integrity_Failure : public Exception
+ {
+ Integrity_Failure(const std::string& err) :
+ Exception("Integrity failure: " + err) {}
+ };
+
+/*
+* Internal_Error Exception
+*/
+struct BOTAN_DLL Internal_Error : public Exception
+ {
+ Internal_Error(const std::string& err) :
+ Exception("Internal error: " + err) {}
+ };
+
+/*
+* Self Test Failure Exception
+*/
+struct BOTAN_DLL Self_Test_Failure : public Internal_Error
+ {
+ Self_Test_Failure(const std::string& err) :
+ Internal_Error("Self test failed: " + err) {}
+ };
+
+}
+
+#endif
diff --git a/botan/src/utils/info.txt b/botan/src/utils/info.txt
new file mode 100644
index 0000000..ab50b88
--- /dev/null
+++ b/botan/src/utils/info.txt
@@ -0,0 +1,33 @@
+realname "Utility Functions"
+
+define UTIL_FUNCTIONS
+
+load_on always
+
+<libs>
+tru64 -> rt
+</libs>
+
+<add>
+bit_ops.h
+bswap.h
+charset.cpp
+charset.h
+exceptn.cpp
+exceptn.h
+loadstor.h
+mem_ops.h
+mlock.cpp
+parsing.cpp
+parsing.h
+rotate.h
+stl_util.h
+types.h
+ui.cpp
+ui.h
+util.cpp
+util.h
+version.cpp
+version.h
+xor_buf.h
+</add>
diff --git a/botan/src/utils/loadstor.h b/botan/src/utils/loadstor.h
new file mode 100644
index 0000000..77ed155
--- /dev/null
+++ b/botan/src/utils/loadstor.h
@@ -0,0 +1,281 @@
+/*
+* Load/Store Operators
+* (C) 1999-2007 Jack Lloyd
+* 2007 Yves Jerschow
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_LOAD_STORE_H__
+#define BOTAN_LOAD_STORE_H__
+
+#include <botan/types.h>
+#include <botan/bswap.h>
+#include <botan/rotate.h>
+
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+
+#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
+
+#define BOTAN_ENDIAN_N2B(x) (x)
+#define BOTAN_ENDIAN_B2N(x) (x)
+
+#define BOTAN_ENDIAN_N2L(x) reverse_bytes(x)
+#define BOTAN_ENDIAN_L2N(x) reverse_bytes(x)
+
+#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
+
+#define BOTAN_ENDIAN_N2L(x) (x)
+#define BOTAN_ENDIAN_L2N(x) (x)
+
+#define BOTAN_ENDIAN_N2B(x) reverse_bytes(x)
+#define BOTAN_ENDIAN_B2N(x) reverse_bytes(x)
+
+#endif
+
+#endif
+
+namespace Botan {
+
+/*
+* Byte Extraction Function
+*/
+template<typename T> inline byte get_byte(u32bit byte_num, T input)
+ {
+ return (input >> ((sizeof(T)-1-(byte_num&(sizeof(T)-1))) << 3));
+ }
+
+/*
+* Byte to Word Conversions
+*/
+inline u16bit make_u16bit(byte i0, byte i1)
+ {
+ return ((static_cast<u16bit>(i0) << 8) | i1);
+ }
+
+inline u32bit make_u32bit(byte i0, byte i1, byte i2, byte i3)
+ {
+ return ((static_cast<u32bit>(i0) << 24) |
+ (static_cast<u32bit>(i1) << 16) |
+ (static_cast<u32bit>(i2) << 8) |
+ (static_cast<u32bit>(i3)));
+ }
+
+inline u64bit make_u64bit(byte i0, byte i1, byte i2, byte i3,
+ byte i4, byte i5, byte i6, byte i7)
+ {
+ return ((static_cast<u64bit>(i0) << 56) |
+ (static_cast<u64bit>(i1) << 48) |
+ (static_cast<u64bit>(i2) << 40) |
+ (static_cast<u64bit>(i3) << 32) |
+ (static_cast<u64bit>(i4) << 24) |
+ (static_cast<u64bit>(i5) << 16) |
+ (static_cast<u64bit>(i6) << 8) |
+ (static_cast<u64bit>(i7)));
+ }
+
+/*
+* Endian-Specific Word Loading Operations
+*/
+template<typename T>
+inline T load_be(const byte in[], u32bit off)
+ {
+ in += off * sizeof(T);
+ T out = 0;
+ for(u32bit j = 0; j != sizeof(T); j++)
+ out = (out << 8) | in[j];
+ return out;
+ }
+
+template<typename T>
+inline T load_le(const byte in[], u32bit off)
+ {
+ in += off * sizeof(T);
+ T out = 0;
+ for(u32bit j = 0; j != sizeof(T); j++)
+ out = (out << 8) | in[sizeof(T)-1-j];
+ return out;
+ }
+
+template<>
+inline u16bit load_be<u16bit>(const byte in[], u32bit off)
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u16bit*>(in) + off));
+#else
+ in += off * sizeof(u16bit);
+ return make_u16bit(in[0], in[1]);
+#endif
+ }
+
+template<>
+inline u16bit load_le<u16bit>(const byte in[], u32bit off)
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u16bit*>(in) + off));
+#else
+ in += off * sizeof(u16bit);
+ return make_u16bit(in[1], in[0]);
+#endif
+ }
+
+template<>
+inline u32bit load_be<u32bit>(const byte in[], u32bit off)
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u32bit*>(in) + off));
+#else
+ in += off * sizeof(u32bit);
+ return make_u32bit(in[0], in[1], in[2], in[3]);
+#endif
+ }
+
+template<>
+inline u32bit load_le<u32bit>(const byte in[], u32bit off)
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u32bit*>(in) + off));
+#else
+ in += off * sizeof(u32bit);
+ return make_u32bit(in[3], in[2], in[1], in[0]);
+#endif
+ }
+
+template<>
+inline u64bit load_be<u64bit>(const byte in[], u32bit off)
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ return BOTAN_ENDIAN_N2B(*(reinterpret_cast<const u64bit*>(in) + off));
+#else
+ in += off * sizeof(u64bit);
+ return make_u64bit(in[0], in[1], in[2], in[3],
+ in[4], in[5], in[6], in[7]);
+#endif
+ }
+
+template<>
+inline u64bit load_le<u64bit>(const byte in[], u32bit off)
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ return BOTAN_ENDIAN_N2L(*(reinterpret_cast<const u64bit*>(in) + off));
+#else
+ in += off * sizeof(u64bit);
+ return make_u64bit(in[7], in[6], in[5], in[4],
+ in[3], in[2], in[1], in[0]);
+#endif
+ }
+
+/*
+* Endian-Specific Word Storing Operations
+*/
+inline void store_be(u16bit in, byte out[2])
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ *reinterpret_cast<u16bit*>(out) = BOTAN_ENDIAN_B2N(in);
+#else
+ out[0] = get_byte(0, in);
+ out[1] = get_byte(1, in);
+#endif
+ }
+
+inline void store_le(u16bit in, byte out[2])
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ *reinterpret_cast<u16bit*>(out) = BOTAN_ENDIAN_L2N(in);
+#else
+ out[0] = get_byte(1, in);
+ out[1] = get_byte(0, in);
+#endif
+ }
+
+inline void store_be(u32bit in, byte out[4])
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ *reinterpret_cast<u32bit*>(out) = BOTAN_ENDIAN_B2N(in);
+#else
+ out[0] = get_byte(0, in);
+ out[1] = get_byte(1, in);
+ out[2] = get_byte(2, in);
+ out[3] = get_byte(3, in);
+#endif
+ }
+
+inline void store_le(u32bit in, byte out[4])
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ *reinterpret_cast<u32bit*>(out) = BOTAN_ENDIAN_L2N(in);
+#else
+ out[0] = get_byte(3, in);
+ out[1] = get_byte(2, in);
+ out[2] = get_byte(1, in);
+ out[3] = get_byte(0, in);
+#endif
+ }
+
+inline void store_be(u64bit in, byte out[8])
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ *reinterpret_cast<u64bit*>(out) = BOTAN_ENDIAN_B2N(in);
+#else
+ out[0] = get_byte(0, in);
+ out[1] = get_byte(1, in);
+ out[2] = get_byte(2, in);
+ out[3] = get_byte(3, in);
+ out[4] = get_byte(4, in);
+ out[5] = get_byte(5, in);
+ out[6] = get_byte(6, in);
+ out[7] = get_byte(7, in);
+#endif
+ }
+
+inline void store_le(u64bit in, byte out[8])
+ {
+#if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK
+ *reinterpret_cast<u64bit*>(out) = BOTAN_ENDIAN_L2N(in);
+#else
+ out[0] = get_byte(7, in);
+ out[1] = get_byte(6, in);
+ out[2] = get_byte(5, in);
+ out[3] = get_byte(4, in);
+ out[4] = get_byte(3, in);
+ out[5] = get_byte(2, in);
+ out[6] = get_byte(1, in);
+ out[7] = get_byte(0, in);
+#endif
+ }
+
+template<typename T>
+inline void store_le(byte out[], T a, T b)
+ {
+ store_le(a, out + (0 * sizeof(T)));
+ store_le(b, out + (1 * sizeof(T)));
+ }
+
+template<typename T>
+inline void store_be(byte out[], T a, T b)
+ {
+ store_be(a, out + (0 * sizeof(T)));
+ store_be(b, out + (1 * sizeof(T)));
+ }
+
+template<typename T>
+inline void store_le(byte out[], T a, T b, T c, T d)
+ {
+ store_le(a, out + (0 * sizeof(T)));
+ store_le(b, out + (1 * sizeof(T)));
+ store_le(c, out + (2 * sizeof(T)));
+ store_le(d, out + (3 * sizeof(T)));
+ }
+
+template<typename T>
+inline void store_be(byte out[], T a, T b, T c, T d)
+ {
+ store_be(a, out + (0 * sizeof(T)));
+ store_be(b, out + (1 * sizeof(T)));
+ store_be(c, out + (2 * sizeof(T)));
+ store_be(d, out + (3 * sizeof(T)));
+ }
+
+}
+
+#endif
diff --git a/botan/src/utils/mem_ops.h b/botan/src/utils/mem_ops.h
new file mode 100644
index 0000000..0fcf34b
--- /dev/null
+++ b/botan/src/utils/mem_ops.h
@@ -0,0 +1,40 @@
+/*
+* Memory Operations
+* (C) 1999-2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_MEMORY_OPS_H__
+#define BOTAN_MEMORY_OPS_H__
+
+#include <botan/types.h>
+#include <cstring>
+
+namespace Botan {
+
+/*
+* Memory Manipulation Functions
+*/
+template<typename T> inline void copy_mem(T* out, const T* in, u32bit n)
+ { std::memmove(out, in, sizeof(T)*n); }
+
+template<typename T> inline void clear_mem(T* ptr, u32bit n)
+ { if(n) std::memset(ptr, 0, sizeof(T)*n); }
+
+template<typename T> inline void set_mem(T* ptr, u32bit n, byte val)
+ { std::memset(ptr, val, sizeof(T)*n); }
+
+template<typename T> inline bool same_mem(const T* p1, const T* p2, u32bit n)
+ {
+ bool is_same = true;
+
+ for(u32bit i = 0; i != n; ++i)
+ is_same &= (p1[i] == p2[i]);
+
+ return is_same;
+ }
+
+}
+
+#endif
diff --git a/botan/src/utils/mlock.cpp b/botan/src/utils/mlock.cpp
new file mode 100644
index 0000000..ea0da26
--- /dev/null
+++ b/botan/src/utils/mlock.cpp
@@ -0,0 +1,55 @@
+/*
+* Memory Locking Functions
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/util.h>
+
+#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK)
+ #include <sys/types.h>
+ #include <sys/mman.h>
+#elif defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK)
+ #include <windows.h>
+#endif
+
+namespace Botan {
+
+/*
+* Lock an area of memory into RAM
+*/
+#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) \
+ || defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK)
+bool lock_mem(void* ptr, u32bit bytes)
+#else
+bool lock_mem(void*, u32bit)
+#endif
+ {
+#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK)
+ return (mlock(ptr, bytes) == 0);
+#elif defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK)
+ return (VirtualLock(ptr, bytes) != 0);
+#else
+ return false;
+#endif
+ }
+
+/*
+* Unlock a previously locked region of memory
+*/
+#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) \
+ || defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK)
+void unlock_mem(void* ptr, u32bit bytes)
+#else
+void unlock_mem(void*, u32bit)
+#endif
+ {
+#if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK)
+ munlock(ptr, bytes);
+#elif defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK)
+ VirtualUnlock(ptr, bytes);
+#endif
+ }
+
+}
diff --git a/botan/src/utils/parsing.cpp b/botan/src/utils/parsing.cpp
new file mode 100644
index 0000000..bdb9e79
--- /dev/null
+++ b/botan/src/utils/parsing.cpp
@@ -0,0 +1,288 @@
+/*
+* Parser Functions
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/parsing.h>
+#include <botan/exceptn.h>
+#include <botan/charset.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+/*
+* Convert a string into an integer
+*/
+u32bit to_u32bit(const std::string& number)
+ {
+ u32bit n = 0;
+
+ for(std::string::const_iterator j = number.begin(); j != number.end(); ++j)
+ {
+ const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10;
+
+ byte digit = Charset::char2digit(*j);
+
+ if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5))
+ throw Decoding_Error("to_u32bit: Integer overflow");
+ n *= 10;
+ n += digit;
+ }
+ return n;
+ }
+
+/*
+* Convert an integer into a string
+*/
+std::string to_string(u64bit n, u32bit min_len)
+ {
+ std::string lenstr;
+ if(n)
+ {
+ while(n > 0)
+ {
+ lenstr = Charset::digit2char(n % 10) + lenstr;
+ n /= 10;
+ }
+ }
+ else
+ lenstr = "0";
+
+ while(lenstr.size() < min_len)
+ lenstr = "0" + lenstr;
+
+ return lenstr;
+ }
+
+/*
+* Convert a string into a time duration
+*/
+u32bit timespec_to_u32bit(const std::string& timespec)
+ {
+ if(timespec == "")
+ return 0;
+
+ const char suffix = timespec[timespec.size()-1];
+ std::string value = timespec.substr(0, timespec.size()-1);
+
+ u32bit scale = 1;
+
+ if(Charset::is_digit(suffix))
+ value += suffix;
+ else if(suffix == 's')
+ scale = 1;
+ else if(suffix == 'm')
+ scale = 60;
+ else if(suffix == 'h')
+ scale = 60 * 60;
+ else if(suffix == 'd')
+ scale = 24 * 60 * 60;
+ else if(suffix == 'y')
+ scale = 365 * 24 * 60 * 60;
+ else
+ throw Decoding_Error("timespec_to_u32bit: Bad input " + timespec);
+
+ return scale * to_u32bit(value);
+ }
+
+/*
+* Parse a SCAN-style algorithm name
+*/
+std::vector<std::string> parse_algorithm_name(const std::string& namex)
+ {
+ if(namex.find('(') == std::string::npos &&
+ namex.find(')') == std::string::npos)
+ return std::vector<std::string>(1, namex);
+
+ std::string name = namex, substring;
+ std::vector<std::string> elems;
+ u32bit level = 0;
+
+ elems.push_back(name.substr(0, name.find('(')));
+ name = name.substr(name.find('('));
+
+ for(std::string::const_iterator j = name.begin(); j != name.end(); ++j)
+ {
+ char c = *j;
+
+ if(c == '(')
+ ++level;
+ if(c == ')')
+ {
+ if(level == 1 && j == name.end() - 1)
+ {
+ if(elems.size() == 1)
+ elems.push_back(substring.substr(1));
+ else
+ elems.push_back(substring);
+ return elems;
+ }
+
+ if(level == 0 || (level == 1 && j != name.end() - 1))
+ throw Invalid_Algorithm_Name(namex);
+ --level;
+ }
+
+ if(c == ',' && level == 1)
+ {
+ if(elems.size() == 1)
+ elems.push_back(substring.substr(1));
+ else
+ elems.push_back(substring);
+ substring.clear();
+ }
+ else
+ substring += c;
+ }
+
+ if(substring != "")
+ throw Invalid_Algorithm_Name(namex);
+
+ return elems;
+ }
+
+/*
+* Split the string on slashes
+*/
+std::vector<std::string> split_on(const std::string& str, char delim)
+ {
+ std::vector<std::string> elems;
+ if(str == "") return elems;
+
+ std::string substr;
+ for(std::string::const_iterator j = str.begin(); j != str.end(); ++j)
+ {
+ if(*j == delim)
+ {
+ if(substr != "")
+ elems.push_back(substr);
+ substr.clear();
+ }
+ else
+ substr += *j;
+ }
+
+ if(substr == "")
+ throw Format_Error("Unable to split string: " + str);
+ elems.push_back(substr);
+
+ return elems;
+ }
+
+/*
+* Parse an ASN.1 OID string
+*/
+std::vector<u32bit> parse_asn1_oid(const std::string& oid)
+ {
+ std::string substring;
+ std::vector<u32bit> oid_elems;
+
+ for(std::string::const_iterator j = oid.begin(); j != oid.end(); ++j)
+ {
+ char c = *j;
+
+ if(c == '.')
+ {
+ if(substring == "")
+ throw Invalid_OID(oid);
+ oid_elems.push_back(to_u32bit(substring));
+ substring.clear();
+ }
+ else
+ substring += c;
+ }
+
+ if(substring == "")
+ throw Invalid_OID(oid);
+ oid_elems.push_back(to_u32bit(substring));
+
+ if(oid_elems.size() < 2)
+ throw Invalid_OID(oid);
+
+ return oid_elems;
+ }
+
+/*
+* X.500 String Comparison
+*/
+bool x500_name_cmp(const std::string& name1, const std::string& name2)
+ {
+ std::string::const_iterator p1 = name1.begin();
+ std::string::const_iterator p2 = name2.begin();
+
+ while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
+ while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
+
+ while(p1 != name1.end() && p2 != name2.end())
+ {
+ if(Charset::is_space(*p1))
+ {
+ if(!Charset::is_space(*p2))
+ return false;
+
+ while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
+ while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
+
+ if(p1 == name1.end() && p2 == name2.end())
+ return true;
+ }
+
+ if(!Charset::caseless_cmp(*p1, *p2))
+ return false;
+ ++p1;
+ ++p2;
+ }
+
+ while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
+ while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
+
+ if((p1 != name1.end()) || (p2 != name2.end()))
+ return false;
+ return true;
+ }
+
+/*
+* Convert a decimal-dotted string to binary IP
+*/
+u32bit string_to_ipv4(const std::string& str)
+ {
+ std::vector<std::string> parts = split_on(str, '.');
+
+ if(parts.size() != 4)
+ throw Decoding_Error("Invalid IP string " + str);
+
+ u32bit ip = 0;
+
+ for(size_t j = 0; j != parts.size(); j++)
+ {
+ u32bit octet = to_u32bit(parts[j]);
+
+ if(octet > 255)
+ throw Decoding_Error("Invalid IP string " + str);
+
+ ip = (ip << 8) | (octet & 0xFF);
+ }
+
+ return ip;
+ }
+
+/*
+* Convert an IP address to decimal-dotted string
+*/
+std::string ipv4_to_string(u32bit ip)
+ {
+ std::string str;
+
+ for(size_t j = 0; j != sizeof(ip); j++)
+ {
+ if(j)
+ str += ".";
+ str += to_string(get_byte(j, ip));
+ }
+
+ return str;
+ }
+
+}
diff --git a/botan/src/utils/parsing.h b/botan/src/utils/parsing.h
new file mode 100644
index 0000000..2c29d5b
--- /dev/null
+++ b/botan/src/utils/parsing.h
@@ -0,0 +1,41 @@
+/*
+* Parser Functions
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_PARSER_H__
+#define BOTAN_PARSER_H__
+
+#include <botan/types.h>
+#include <string>
+#include <vector>
+
+namespace Botan {
+
+/*
+* String Parsing Functions
+*/
+BOTAN_DLL std::vector<std::string> parse_algorithm_name(const std::string&);
+BOTAN_DLL std::vector<std::string> split_on(const std::string&, char);
+BOTAN_DLL std::vector<u32bit> parse_asn1_oid(const std::string&);
+BOTAN_DLL bool x500_name_cmp(const std::string&, const std::string&);
+
+/*
+* String/Integer Conversions
+*/
+BOTAN_DLL std::string to_string(u64bit, u32bit = 0);
+BOTAN_DLL u32bit to_u32bit(const std::string&);
+
+BOTAN_DLL u32bit timespec_to_u32bit(const std::string& timespec);
+
+/*
+* String/Network Address Conversions
+*/
+BOTAN_DLL u32bit string_to_ipv4(const std::string&);
+BOTAN_DLL std::string ipv4_to_string(u32bit);
+
+}
+
+#endif
diff --git a/botan/src/utils/rotate.h b/botan/src/utils/rotate.h
new file mode 100644
index 0000000..c8f8d4a
--- /dev/null
+++ b/botan/src/utils/rotate.h
@@ -0,0 +1,30 @@
+/*
+* Word Rotation Operations
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_WORD_ROTATE_H__
+#define BOTAN_WORD_ROTATE_H__
+
+#include <botan/types.h>
+
+namespace Botan {
+
+/*
+* Word Rotation Functions
+*/
+template<typename T> inline T rotate_left(T input, u32bit rot)
+ {
+ return static_cast<T>((input << rot) | (input >> (8*sizeof(T)-rot)));;
+ }
+
+template<typename T> inline T rotate_right(T input, u32bit rot)
+ {
+ return static_cast<T>((input >> rot) | (input << (8*sizeof(T)-rot)));
+ }
+
+}
+
+#endif
diff --git a/botan/src/utils/stl_util.h b/botan/src/utils/stl_util.h
new file mode 100644
index 0000000..18c8b14
--- /dev/null
+++ b/botan/src/utils/stl_util.h
@@ -0,0 +1,86 @@
+/*
+* STL Utility Functions
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_STL_UTIL_H__
+#define BOTAN_STL_UTIL_H__
+
+#include <map>
+
+namespace Botan {
+
+/*
+* Copy-on-Predicate Algorithm
+*/
+template<typename InputIterator, typename OutputIterator, typename Predicate>
+OutputIterator copy_if(InputIterator current, InputIterator end,
+ OutputIterator dest, Predicate copy_p)
+ {
+ while(current != end)
+ {
+ if(copy_p(*current))
+ *dest++ = *current;
+ ++current;
+ }
+ return dest;
+ }
+
+/*
+* Searching through a std::map
+*/
+template<typename K, typename V>
+inline V search_map(const std::map<K, V>& mapping,
+ const K& key,
+ const V& null_result = V())
+ {
+ typename std::map<K, V>::const_iterator i = mapping.find(key);
+ if(i == mapping.end())
+ return null_result;
+ return i->second;
+ }
+
+template<typename K, typename V, typename R>
+inline R search_map(const std::map<K, V>& mapping, const K& key,
+ const R& null_result, const R& found_result)
+ {
+ typename std::map<K, V>::const_iterator i = mapping.find(key);
+ if(i == mapping.end())
+ return null_result;
+ return found_result;
+ }
+
+/*
+* Function adaptor for delete operation
+*/
+template<class T>
+class del_fun : public std::unary_function<T, void>
+ {
+ public:
+ void operator()(T* ptr) { delete ptr; }
+ };
+
+/*
+* Delete the second half of a pair of objects
+*/
+template<typename Pair>
+void delete2nd(Pair& pair)
+ {
+ delete pair.second;
+ }
+
+/*
+* Insert a key/value pair into a multimap
+*/
+template<typename K, typename V>
+void multimap_insert(std::multimap<K, V>& multimap,
+ const K& key, const V& value)
+ {
+ multimap.insert(std::make_pair(key, value));
+ }
+
+}
+
+#endif
diff --git a/botan/src/utils/types.h b/botan/src/utils/types.h
new file mode 100644
index 0000000..304628d
--- /dev/null
+++ b/botan/src/utils/types.h
@@ -0,0 +1,42 @@
+/*
+* Low Level Types
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_TYPES_H__
+#define BOTAN_TYPES_H__
+
+#include <botan/build.h>
+
+namespace Botan {
+
+typedef unsigned char byte;
+typedef unsigned short u16bit;
+typedef unsigned int u32bit;
+
+typedef signed int s32bit;
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+ typedef unsigned __int64 u64bit;
+#elif defined(__KCC)
+ typedef unsigned __long_long u64bit;
+#elif defined(__GNUG__)
+ __extension__ typedef unsigned long long u64bit;
+#else
+ typedef unsigned long long u64bit;
+#endif
+
+static const u32bit DEFAULT_BUFFERSIZE = BOTAN_DEFAULT_BUFFER_SIZE;
+
+}
+
+namespace Botan_types {
+
+using Botan::byte;
+using Botan::u32bit;
+
+}
+
+#endif
diff --git a/botan/src/utils/ui.cpp b/botan/src/utils/ui.cpp
new file mode 100644
index 0000000..e6c3430
--- /dev/null
+++ b/botan/src/utils/ui.cpp
@@ -0,0 +1,36 @@
+/*
+* User Interface
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/ui.h>
+
+namespace Botan {
+
+/*
+* Get a passphrase from the user
+*/
+std::string User_Interface::get_passphrase(const std::string&,
+ const std::string&,
+ UI_Result& action) const
+ {
+ action = OK;
+
+ if(!first_try)
+ action = CANCEL_ACTION;
+
+ return preset_passphrase;
+ }
+
+/*
+* User_Interface Constructor
+*/
+User_Interface::User_Interface(const std::string& preset) :
+ preset_passphrase(preset)
+ {
+ first_try = true;
+ }
+
+}
diff --git a/botan/src/utils/ui.h b/botan/src/utils/ui.h
new file mode 100644
index 0000000..fe62c60
--- /dev/null
+++ b/botan/src/utils/ui.h
@@ -0,0 +1,36 @@
+/*
+* User Interface
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_UI_H__
+#define BOTAN_UI_H__
+
+#include <botan/build.h>
+#include <string>
+
+namespace Botan {
+
+/*
+* User Interface
+*/
+class BOTAN_DLL User_Interface
+ {
+ public:
+ enum UI_Result { OK, CANCEL_ACTION };
+
+ virtual std::string get_passphrase(const std::string&,
+ const std::string&,
+ UI_Result&) const;
+ User_Interface(const std::string& = "");
+ virtual ~User_Interface() {}
+ protected:
+ std::string preset_passphrase;
+ mutable bool first_try;
+ };
+
+}
+
+#endif
diff --git a/botan/src/utils/util.cpp b/botan/src/utils/util.cpp
new file mode 100644
index 0000000..84dfd1a
--- /dev/null
+++ b/botan/src/utils/util.cpp
@@ -0,0 +1,68 @@
+/*
+* Utility Functions
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/util.h>
+#include <algorithm>
+#include <cmath>
+
+namespace Botan {
+
+/*
+* Round up n to multiple of align_to
+*/
+u32bit round_up(u32bit n, u32bit align_to)
+ {
+ if(n % align_to || n == 0)
+ n += align_to - (n % align_to);
+ return n;
+ }
+
+/*
+* Round down n to multiple of align_to
+*/
+u32bit round_down(u32bit n, u32bit align_to)
+ {
+ return (n - (n % align_to));
+ }
+
+/*
+* Choose the exponent size for a DL group
+*/
+u32bit dl_work_factor(u32bit bits)
+ {
+#if 0
+ /*
+ These values were taken from RFC 3526
+ */
+ if(bits <= 1536)
+ return 90;
+ else if(bits <= 2048)
+ return 110;
+ else if(bits <= 3072)
+ return 130;
+ else if(bits <= 4096)
+ return 150;
+ else if(bits <= 6144)
+ return 170;
+ else if(bits <= 8192)
+ return 190;
+ return 256;
+#else
+ const u32bit MIN_ESTIMATE = 64;
+
+ const double log_x = bits / 1.44;
+
+ const double strength =
+ 2.76 * std::pow(log_x, 1.0/3.0) * std::pow(std::log(log_x), 2.0/3.0);
+
+ if(strength > MIN_ESTIMATE)
+ return static_cast<u32bit>(strength);
+ return MIN_ESTIMATE;
+#endif
+ }
+
+}
diff --git a/botan/src/utils/util.h b/botan/src/utils/util.h
new file mode 100644
index 0000000..ac78673
--- /dev/null
+++ b/botan/src/utils/util.h
@@ -0,0 +1,39 @@
+/*
+* Utility Functions
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_UTIL_H__
+#define BOTAN_UTIL_H__
+
+#include <botan/types.h>
+
+namespace Botan {
+
+/*
+* Time Access Functions
+*/
+BOTAN_DLL u64bit system_time();
+
+/*
+* Memory Locking Functions
+*/
+BOTAN_DLL bool lock_mem(void*, u32bit);
+BOTAN_DLL void unlock_mem(void*, u32bit);
+
+/*
+* Misc Utility Functions
+*/
+BOTAN_DLL u32bit round_up(u32bit, u32bit);
+BOTAN_DLL u32bit round_down(u32bit, u32bit);
+
+/*
+* Work Factor Estimates
+*/
+BOTAN_DLL u32bit dl_work_factor(u32bit);
+
+}
+
+#endif
diff --git a/botan/src/utils/version.cpp b/botan/src/utils/version.cpp
new file mode 100644
index 0000000..d540864
--- /dev/null
+++ b/botan/src/utils/version.cpp
@@ -0,0 +1,36 @@
+/*
+* Version Information
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/version.h>
+#include <botan/parsing.h>
+
+namespace Botan {
+
+/*
+ These are intentionally compiled rather than inlined, so an
+ application running against a shared library can test the true
+ version they are running against.
+*/
+
+/*
+* Return the version as a string
+*/
+std::string version_string()
+ {
+ return to_string(version_major()) + "." +
+ to_string(version_minor()) + "." +
+ to_string(version_patch());
+ }
+
+/*
+* Return parts of the version as integers
+*/
+u32bit version_major() { return BOTAN_VERSION_MAJOR; }
+u32bit version_minor() { return BOTAN_VERSION_MINOR; }
+u32bit version_patch() { return BOTAN_VERSION_PATCH; }
+
+}
diff --git a/botan/src/utils/version.h b/botan/src/utils/version.h
new file mode 100644
index 0000000..3cc44e8
--- /dev/null
+++ b/botan/src/utils/version.h
@@ -0,0 +1,61 @@
+/*
+* Version Information
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_VERSION_H__
+#define BOTAN_VERSION_H__
+
+#include <botan/types.h>
+#include <string>
+
+namespace Botan {
+
+/*
+* Get information describing the version
+*/
+
+/**
+* Get the version string identifying the version of Botan.
+* @return the version string
+*/
+BOTAN_DLL std::string version_string();
+
+/**
+* Get the major version number.
+* @return the major version number
+*/
+BOTAN_DLL u32bit version_major();
+
+/**
+* Get the minor version number.
+* @return the minor version number
+*/
+BOTAN_DLL u32bit version_minor();
+
+/**
+* Get the patch number.
+* @return the patch number
+*/
+BOTAN_DLL u32bit version_patch();
+
+/*
+* Macros for compile-time version checks
+*/
+#define BOTAN_VERSION_CODE_FOR(a,b,c) ((a << 16) | (b << 8) | (c))
+
+/**
+* Compare using BOTAN_VERSION_CODE_FOR, as in
+* # if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,8,0)
+* # error "Botan version too old"
+* # endif
+*/
+#define BOTAN_VERSION_CODE BOTAN_VERSION_CODE_FOR(BOTAN_VERSION_MAJOR, \
+ BOTAN_VERSION_MINOR, \
+ BOTAN_VERSION_PATCH)
+
+}
+
+#endif
diff --git a/botan/src/utils/xor_buf.h b/botan/src/utils/xor_buf.h
new file mode 100644
index 0000000..39781f0
--- /dev/null
+++ b/botan/src/utils/xor_buf.h
@@ -0,0 +1,74 @@
+/**
+* XOR operations
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_XOR_BUF_H__
+#define BOTAN_XOR_BUF_H__
+
+#include <botan/types.h>
+
+namespace Botan {
+
+/**
+* XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length
+* @param out the input/output buffer
+* @param in the read-only input buffer
+* @param length the length of the buffers
+*/
+inline void xor_buf(byte out[], const byte in[], u32bit length)
+ {
+ while(length >= 8)
+ {
+#if BOTAN_UNALIGNED_LOADSTOR_OK
+ *reinterpret_cast<u64bit*>(out) ^= *reinterpret_cast<const u64bit*>(in);
+#else
+ out[0] ^= in[0]; out[1] ^= in[1];
+ out[2] ^= in[2]; out[3] ^= in[3];
+ out[4] ^= in[4]; out[5] ^= in[5];
+ out[6] ^= in[6]; out[7] ^= in[7];
+#endif
+
+ out += 8; in += 8; length -= 8;
+ }
+ for(u32bit j = 0; j != length; ++j)
+ out[j] ^= in[j];
+ }
+
+/**
+* XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length
+* @param out the output buffer
+* @param in the first input buffer
+* @param in2 the second output buffer
+* @param length the length of the three buffers
+*/
+inline void xor_buf(byte out[],
+ const byte in[],
+ const byte in2[],
+ u32bit length)
+ {
+ while(length >= 8)
+ {
+#if BOTAN_UNALIGNED_LOADSTOR_OK
+ *reinterpret_cast<u64bit*>(out) =
+ *reinterpret_cast<const u64bit*>(in) ^
+ *reinterpret_cast<const u64bit*>(in2);
+#else
+ out[0] = in[0] ^ in2[0]; out[1] = in[1] ^ in2[1];
+ out[2] = in[2] ^ in2[2]; out[3] = in[3] ^ in2[3];
+ out[4] = in[4] ^ in2[4]; out[5] = in[5] ^ in2[5];
+ out[6] = in[6] ^ in2[6]; out[7] = in[7] ^ in2[7];
+#endif
+
+ in += 8; in2 += 8; out += 8; length -= 8;
+ }
+
+ for(u32bit j = 0; j != length; ++j)
+ out[j] = in[j] ^ in2[j];
+ }
+
+}
+
+#endif