The unified diff between revisions [8968f4b3..] and [0fcc955d..] is displayed below. It can also be downloaded as a raw diff.

#
#
# delete "Attic/misc/config/todo.txt"
#
# rename "Attic/misc/python/src/algos.cpp"
#     to "Attic/misc/python/src/macs.cpp"
#
# add_dir "Attic/modules/alg_amd64"
#
# add_file "Attic/misc/python/src/stream.cpp"
#  content [330e6cfed963546685e6bf5ed7ca5ea7f21d849d]
#
# add_file "Attic/modules/alg_amd64/asm_macr.h"
#  content [13eddd7cabf787c96562197946ff29188e9b3dde]
#
# add_file "Attic/modules/alg_amd64/modinfo.txt"
#  content [569a9e71549b535a223f47c243b4bb1376b95f1e]
#
# add_file "Attic/modules/alg_amd64/mp_muladd.S"
#  content [247f2816ce791ce9da6735c23002a069edc66404]
#
# patch "Attic/checks/check.cpp"
#  from [358893c0e30d78d71938cb8b74854cb27d23b70e]
#    to [0d02e5ec66b09896d807c65c15227341bc163fff]
#
# patch "Attic/checks/clock.cpp"
#  from [b8133544327e5b4b3111a0abd739efefdb0c19ab]
#    to [15d1f1ebc60b0eaf5abd56b7c35af454af0c88de]
#
# patch "Attic/checks/pk_bench.cpp"
#  from [280cf510191bf4a7936c4bdb9e938599ca62eb6b]
#    to [b582c96d8ff536e33d520bc93c2089515f88c880]
#
# patch "Attic/configure.pl"
#  from [b7c300891b441b0fc307677f105fc63e07a90a47]
#    to [4a96f30300f00ffc8920d0059e681052bcb59c5b]
#
# patch "Attic/doc/api.tex"
#  from [e40b2e58125af2013719a251f78cae6483accc5c]
#    to [24f0ee532fd3c18d3979a41c2750bf4114ce6402]
#
# patch "Attic/doc/building.tex"
#  from [0cecc39c901fed7f95687dd9be9f15bedd175448]
#    to [766f68650552872ddafc3091e70990ecf7e3892b]
#
# patch "Attic/misc/config/arch/amd64"
#  from [4a8ddf11d915fb90de3fdf9800d6080c83640c8b]
#    to [3bda1ee7f9267f5af7c95766e9eee95c7e5dbb5d]
#
# patch "Attic/misc/config/buildh.in"
#  from [75037518b4a690490e86271ef2397b64661b892d]
#    to [f390f744fb5b88b61bf08eec18e047d5b5122d35]
#
# patch "Attic/misc/config/cc/gcc"
#  from [141963a58d991c8890197a0a1ac06befb785eb23]
#    to [b8325689146701fd42f035c20d39185cdc5772a6]
#
# patch "Attic/misc/python/src/core.cpp"
#  from [1e92d8a2a89f4f0abcf33b0981ff47fb5bf45347]
#    to [54a44c78ed3d2ad69cbae4ae7782fb0b78483e0c]
#
# patch "Attic/misc/python/src/macs.cpp"
#  from [89ffde42ff0a3beecf9f0bee33c765a5ae8a699e]
#    to [8ba2a2fc0503648e27ebce9e19aa8b54d063bd81]
#
# patch "Attic/misc/python/src/pk.cpp"
#  from [c72e2ba3d2d906d909de4b9cf5e684517a8eb134]
#    to [403f3e48978c042df5bf23a1d3036bedef7d651f]
#
# patch "Attic/modules/alg_ia32/asm_macr.h"
#  from [b9f54c5c1ebf73c1f0e3a2e19636420112428164]
#    to [c8ddcf00f92a14abe6b9c72b86ee4d04bfe489a0]
#
# patch "Attic/modules/alg_ia32/mp_muladd.S"
#  from [f47fec487fb0622e334c90cb71be2c43b1656389]
#    to [d6ce402b02bb7d1751edc8119bc82fd8629be504]
#
# patch "Attic/modules/eng_aep/modinfo.txt"
#  from [b84fbf8d0855e1d4d84fe1d2f2ced1032798b5a0]
#    to [579ec293b81755160084c68cf57d17978f851745]
#
# patch "emsa1.cpp"
#  from [1dd0e80f0dc5bfbd718e2edc2e6de80fa482b50c]
#    to [e12d485d4f2484e6b53cd52288486cb56419b26c]
#
# patch "emsa2.cpp"
#  from [a4d8301f23805ba4bb2554591dfc20e373bce4ca]
#    to [39f86a2ed053f0ddb8a0e0fb032ea9007149d27b]
#
# patch "emsa3.cpp"
#  from [367b509f38995bb4978b8f514239c97989fb63b3]
#    to [0712cedbf4b4da5381aa6ec751798e527bac5239]
#
# patch "emsa4.cpp"
#  from [a45dd0f15cdb2cb8f81d8493b44248f206bf44f2]
#    to [37c2f6432f8c13d345aedd7e5155aa3f4fb75e39]
#
# patch "kdf.cpp"
#  from [875f93344551fe6e76ca4c86660937d2ec190c60]
#    to [961788f9806afb6dfd141703c9c9eb7f99ecf64c]
#
# patch "keypair.cpp"
#  from [b989bff406ff022391d3484840d085d4060715de]
#    to [2c64955c5e28515d0029e50937107dd9a91e3b48]
#
# patch "pk_util.cpp"
#  from [63673b6371f30e1bc06a7ff8e06ab6b9d998bf8b]
#    to [8237a1130cf67101cdc62f6f63c5378a27ff240b]
#
============================================================
--- Attic/misc/python/src/stream.cpp	330e6cfed963546685e6bf5ed7ca5ea7f21d849d
+++ Attic/misc/python/src/stream.cpp	330e6cfed963546685e6bf5ed7ca5ea7f21d849d
@@ -0,0 +1,54 @@
+/*************************************************
+* Boost.Python module definition                 *
+* (C) 1999-2006 The Botan Project                *
+*************************************************/
+
+#include <botan/botan.h>
+using namespace Botan;
+
+#include "common.h"
+
+class Py_StreamCipher
+   {
+   public:
+      u32bit keylength_min() const { return cipher->MINIMUM_KEYLENGTH; }
+      u32bit keylength_max() const { return cipher->MAXIMUM_KEYLENGTH; }
+      u32bit keylength_mod() const { return cipher->KEYLENGTH_MULTIPLE; }
+
+      void set_key(const OctetString& key) { cipher->set_key(key); }
+      bool valid_keylength(u32bit kl) const
+         {
+         return cipher->valid_keylength(kl);
+         }
+
+      std::string name() const { return cipher->name(); }
+      void clear() throw() { cipher->clear(); }
+
+      std::string crypt(const std::string& in) const
+         {
+         SecureVector<byte> out(in.size());
+         cipher->encrypt((const byte*)in.data(), out.begin(), in.size());
+         return std::string((const char*)out.begin(), out.size());
+         }
+
+      Py_StreamCipher(const std::string& name)
+         {
+         cipher = get_stream_cipher(name);
+         }
+      ~Py_StreamCipher() { delete cipher; }
+   private:
+      StreamCipher* cipher;
+   };
+
+void export_stream_ciphers()
+   {
+   python::class_<Py_StreamCipher>("StreamCipher", python::init<std::string>())
+      .add_property("keylength_min", &Py_StreamCipher::keylength_min)
+      .add_property("keylength_max", &Py_StreamCipher::keylength_max)
+      .add_property("keylength_mod", &Py_StreamCipher::keylength_mod)
+      .add_property("name", &Py_StreamCipher::name)
+      .def("clear", &Py_StreamCipher::clear)
+      .def("valid_keylength", &Py_StreamCipher::valid_keylength)
+      .def("set_key", &Py_StreamCipher::set_key)
+      .def("crypt", &Py_StreamCipher::crypt);
+   }
============================================================
--- Attic/modules/alg_amd64/asm_macr.h	13eddd7cabf787c96562197946ff29188e9b3dde
+++ Attic/modules/alg_amd64/asm_macr.h	13eddd7cabf787c96562197946ff29188e9b3dde
@@ -0,0 +1,84 @@
+/*************************************************
+* Assembly Macros Header File                    *
+* (C) 1999-2006 The Botan Project                *
+*************************************************/
+
+#ifndef BOTAN_EXT_ASM_MACROS_H__
+#define BOTAN_EXT_ASM_MACROS_H__
+
+/*************************************************
+* General/Global Macros                          *
+*************************************************/
+#define ALIGN .p2align 4,,15
+
+#define START_LISTING(FILENAME) \
+   .file #FILENAME;             \
+   .text;                       \
+   ALIGN;
+
+/*************************************************
+* 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) \
+   cmp IMM(NUM), REG;                  \
+   jne LABEL##_LOOP
+
+#define LOOP_UNTIL_LT(REG, NUM, LABEL) \
+   cmp IMM(NUM), REG;                  \
+   jge LABEL##_LOOP
+
+/*************************************************
+ 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
+
+/*************************************************
+* Memory Access Operations                       *
+*************************************************/
+#define ARRAY8(REG, NUM) 8*(NUM)(REG)
+
+#define ASSIGN(TO, FROM) mov FROM, TO
+
+/*************************************************
+* ALU Operations                                 *
+*************************************************/
+#define IMM(VAL) $VAL
+
+#define ADD(TO, FROM) addq FROM, TO
+#define ADD_LAST_CARRY(REG) adcq IMM(0), REG
+#define ADD_IMM(TO, NUM) ADD(TO, IMM(NUM))
+#define ADD_W_CARRY(TO1, TO2, FROM) addq FROM, TO1; adcq IMM(0), TO2;
+#define SUB_IMM(TO, NUM) sub IMM(NUM), TO
+#define MUL(REG) mulq REG
+
+#define XOR(TO, FROM) xorq FROM, TO
+#define AND(TO, FROM) andq FROM, TO
+#define OR(TO, FROM) orq FROM, TO
+#define NOT(REG) notq REG
+#define ZEROIZE(REG) XOR(REG, REG)
+
+#define RETURN_VALUE_IS(V) ASSIGN(%rax, V)
+
+#endif
============================================================
--- Attic/modules/alg_amd64/modinfo.txt	569a9e71549b535a223f47c243b4bb1376b95f1e
+++ Attic/modules/alg_amd64/modinfo.txt	569a9e71549b535a223f47c243b4bb1376b95f1e
@@ -0,0 +1,34 @@
+realname "Algorithm x86-64 Assembler"
+
+mp_bits 64
+
+<replace>
+#sha160.cpp
+</replace>
+
+<ignore>
+mp_muladd.cpp
+</ignore>
+
+<add>
+asm_macr.h
+mp_muladd.S
+#sha1core.S
+</add>
+
+<arch>
+amd64
+</arch>
+
+<cc>
+gcc
+</cc>
+
+# ELF systems
+<os>
+linux
+freebsd
+netbsd
+openbsd
+solaris
+</os>
============================================================
--- Attic/modules/alg_amd64/mp_muladd.S	247f2816ce791ce9da6735c23002a069edc66404
+++ Attic/modules/alg_amd64/mp_muladd.S	247f2816ce791ce9da6735c23002a069edc66404
@@ -0,0 +1,66 @@
+/*************************************************
+* Multiply/Add Algorithm Source File             *
+* (C) 1999-2006 The Botan Project                *
+*************************************************/
+
+#include <botan/asm_macr.h>
+
+START_LISTING(mp_muladd.S)
+
+START_FUNCTION(bigint_mul_add_words)
+
+#define LOOP_CTR %r11d
+#define X_ARR %rsi
+#define Z_ARR %rdi
+#define Y %rcx
+#define CARRY %r8
+#define Z_WORD %r9
+#define MUL_LO %rax
+#define MUL_HI %rdx
+
+   ZEROIZE(CARRY)
+
+   ASSIGN(LOOP_CTR, %edx)
+
+   JUMP_IF_ZERO(LOOP_CTR, .DONE)
+   JUMP_IF_LT(LOOP_CTR, 8, .MULADD1_LOOP)
+
+#define MULADD_OP(N)                  \
+   ASSIGN(MUL_LO, ARRAY8(X_ARR, N)) ; \
+   ASSIGN(Z_WORD, ARRAY8(Z_ARR, N)) ; \
+   MUL(Y)                           ; \
+   ADD(Z_WORD, CARRY)               ; \
+   ASSIGN(CARRY, MUL_HI)            ; \
+   ADD_LAST_CARRY(CARRY)            ; \
+   ADD(Z_WORD, MUL_LO)              ; \
+   ADD_LAST_CARRY(CARRY)            ; \
+   ASSIGN(ARRAY8(Z_ARR, N), Z_WORD)
+
+START_LOOP(.MULADD8)
+   MULADD_OP(0)
+   MULADD_OP(1)
+   MULADD_OP(2)
+   MULADD_OP(3)
+   MULADD_OP(4)
+   MULADD_OP(5)
+   MULADD_OP(6)
+   MULADD_OP(7)
+
+   SUB_IMM(LOOP_CTR, 8)
+   ADD_IMM(Z_ARR, 64)
+   ADD_IMM(X_ARR, 64)
+LOOP_UNTIL_LT(LOOP_CTR, 8, .MULADD8)
+
+   JUMP_IF_ZERO(LOOP_CTR, .DONE)
+
+START_LOOP(.MULADD1)
+   MULADD_OP(0)
+
+   SUB_IMM(LOOP_CTR, 1)
+   ADD_IMM(Z_ARR, 8)
+   ADD_IMM(X_ARR, 8)
+LOOP_UNTIL_EQ(LOOP_CTR, 0, .MULADD1)
+
+.DONE:
+   RETURN_VALUE_IS(CARRY)
+END_FUNCTION(bigint_mul_add_words)
============================================================
--- Attic/checks/check.cpp	358893c0e30d78d71938cb8b74854cb27d23b70e
+++ Attic/checks/check.cpp	0d02e5ec66b09896d807c65c15227341bc163fff
@@ -59,16 +59,22 @@ int main(int argc, char* argv[])
             }
          }

+      const bool html = opts.is_set("html");
+
       if(opts.is_set("bench-algo"))
          {
-         const std::string alg = opts.value("bench-algo");
-         u32bit found = bench_algo(alg, seconds);
-         if(!found) // maybe it's a PK algorithm
-            bench_pk(alg, false, seconds);
+         std::vector<std::string> algs =
+            Botan::split_on(opts.value("bench-algo"), ',');
+
+         for(u32bit j = 0; j != algs.size(); j++)
+            {
+            const std::string alg = algs[j];
+            u32bit found = bench_algo(alg, seconds);
+            if(!found) // maybe it's a PK algorithm
+               bench_pk(alg, html, seconds);
+            }
          }

-      const bool html = opts.is_set("html");
-
       if(opts.is_set("benchmark"))
          benchmark("All", html, seconds);
       else if(opts.is_set("bench-type"))
============================================================
--- Attic/checks/clock.cpp	b8133544327e5b4b3111a0abd739efefdb0c19ab
+++ Attic/checks/clock.cpp	15d1f1ebc60b0eaf5abd56b7c35af454af0c88de
@@ -16,7 +16,7 @@ using namespace Botan;
 #define USE_RDTSC         0

 /* If using USE_RDTSC, set to your CPU's Mhz */
-#define CPU_MHZ 1333
+#define CPU_MHZ 1866

 #if USE_CLOCK

============================================================
--- Attic/checks/pk_bench.cpp	280cf510191bf4a7936c4bdb9e938599ca62eb6b
+++ Attic/checks/pk_bench.cpp	b582c96d8ff536e33d520bc93c2089515f88c880
@@ -252,24 +252,39 @@ void bench_pk(const std::string& algo, b

    }

-void print_result(bool, u32bit runs, u64bit clocks_used,
+void print_result(bool html, u32bit runs, u64bit clocks_used,
                   const std::string& algo_name, const std::string& op)
    {
-   std::cout << algo_name << ": ";
+   double seconds = (double)clocks_used / get_ticks();
+   double mseconds_per_run = 1000 * (seconds / runs);
+   double runs_per_sec = runs / seconds;

-   double seconds = (double)clocks_used / get_ticks();
-   std::cout.setf(std::ios::fixed, std::ios::floatfield);
-   std::cout.precision(2);

+   if(html)
+      {
+      std::cout << "   <TR><TH>" << algo_name << " (" << op << ") <TH>";
+
 #if PRINT_MS_PER_OP
-   // print milliseconds / op
-   double mseconds_per_run = 1000 * (seconds / runs);
-   std::cout << mseconds_per_run << " ms / " << op << std::endl;
+      std::cout << mseconds_per_run;
 #else
-   // print ops / second
-   double runs_per_sec = runs / seconds;
-   std::cout << runs_per_sec << " ops / second (" << op << ")" << std::endl;
+      std::cout << runs_per_sec;
 #endif
+
+      std::cout << std::endl;
+      }
+   else
+      {
+      std::cout << algo_name << ": ";
+
+      std::cout.setf(std::ios::fixed, std::ios::floatfield);
+      std::cout.precision(2);
+
+#if PRINT_MS_PER_OP
+      std::cout << mseconds_per_run << " ms / " << op << std::endl;
+#else
+      std::cout << runs_per_sec << " ops / second (" << op << ")" << std::endl;
+#endif
+      }
    }

 void bench_enc(PK_Encryptor* enc, const std::string& algo_name,
============================================================
--- Attic/configure.pl	b7c300891b441b0fc307677f105fc63e07a90a47
+++ Attic/configure.pl	4a96f30300f00ffc8920d0059e681052bcb59c5b
@@ -22,7 +22,7 @@ my @DOCS = (
    'api.pdf', 'tutorial.pdf', 'fips140.pdf',
    'api.tex', 'tutorial.tex', 'fips140.tex',
    'credits.txt', 'info.txt', 'license.txt', 'log.txt',
-   'thanks.txt', 'todo.txt', 'botan.rc', 'pgpkeys.asc');
+   'thanks.txt', 'todo.txt', 'pgpkeys.asc');

 my %MODULE_SETS =
     (
@@ -44,13 +44,23 @@ sub main {
 # Main Driver                                    #
 ##################################################
 sub main {
-    %CPU = read_info_files('arch', \&get_arch_info);
-    %OPERATING_SYSTEM = read_info_files('os', \&get_os_info);
-    %COMPILER = read_info_files('cc', \&get_cc_info);
-    %MODULES = read_module_files('modules');
+    my $config = {};

-    my $config = {};
+    my $base_dir = where_am_i();

+    $$config{'base-dir'} = $base_dir;
+    $$config{'config-dir'} = File::Spec->catdir($base_dir, 'misc', 'config');
+    $$config{'mods-dir'} = File::Spec->catdir($base_dir, 'modules');
+    $$config{'src-dir'} = File::Spec->catdir($base_dir, 'src');
+    $$config{'include-dir'} = File::Spec->catdir($base_dir, 'include');
+    $$config{'checks-dir'} = File::Spec->catdir($base_dir, 'checks');
+    $$config{'doc-dir'} = File::Spec->catdir($base_dir, 'doc');
+
+    %CPU = read_info_files($config, 'arch', \&get_arch_info);
+    %OPERATING_SYSTEM = read_info_files($config, 'os', \&get_os_info);
+    %COMPILER = read_info_files($config, 'cc', \&get_cc_info);
+    %MODULES = read_module_files($config);
+
     add_to($config, {
         'version_major' => $MAJOR_VERSION,
         'version_minor' => $MINOR_VERSION,
@@ -98,11 +108,18 @@ sub main {
         'mp_bits'       => find_mp_bits(@modules),
         'mod_libs'      => [ using_libs($os, @modules) ],

-        'sources'       => { map_to('src', dir_list('src')) },
-        'includes'      => { map_to('include', dir_list('include')) },
-        'check_src'     => { map_to('checks',
-                                    grep { $_ ne 'keys' and !m@\.(dat|h)$@ }
-                                    dir_list('checks'))
+        'sources'       => {
+            map_to($$config{'src-dir'}, dir_list($$config{'src-dir'}))
+            },
+
+        'includes'      => {
+            map_to($$config{'include-dir'}, dir_list($$config{'include-dir'}))
+            },
+
+        'check_src'     => {
+            map_to($$config{'checks-dir'},
+                   grep { $_ ne 'keys' and !m@\.(dat|h)$@ }
+                      dir_list($$config{'checks-dir'}))
             }
         });

@@ -114,7 +131,7 @@ sub main {

     write_pkg_config($config);

-    process_template(File::Spec->catfile('misc', 'config', 'buildh.in'),
+    process_template(File::Spec->catfile($$config{'config-dir'}, 'buildh.in'),
                      File::Spec->catfile($$config{'build-dir'}, 'build.h'),
                      $config);
     $$config{'includes'}{'build.h'} = $$config{'build-dir'};
@@ -124,6 +141,12 @@ sub main {
     generate_makefile($config);
 }

+sub where_am_i {
+    my ($volume,$dir,$file) = File::Spec->splitpath($0);
+    my $src_dir = File::Spec->catpath($volume, $dir, '');
+    return $src_dir;
+}
+
 ##################################################
 # Diagnostics                                    #
 ##################################################
@@ -526,8 +549,7 @@ sub my_compiler {
     croak('my_compiler called, but no compiler set in config')
         unless defined $cc and $cc ne '';

-    croak("unknown compiler $cc")
-        unless defined $COMPILER{$cc};
+    croak("unknown compiler $cc") unless defined $COMPILER{$cc};

     return %{$COMPILER{$cc}};
 }
@@ -869,10 +891,12 @@ sub file_type {
 #                                                #
 ##################################################
 sub file_type {
-    my ($file) = @_;
+    my ($config, $file) = @_;

-    return ('sources', 'src') if($file =~ /\.cpp$/ or $file =~ /\.S$/);
-    return ('includes', 'include') if($file =~ /\.h$/);
+    return ('sources', $$config{'src-dir'})
+        if($file =~ /\.cpp$/ or $file =~ /\.S$/);
+    return ('includes', $$config{'include-dir'})
+        if($file =~ /\.h$/);

     croak('file_type() - don\'t know what sort of file ', $file, ' is');
 }
@@ -880,9 +904,9 @@ sub add_file {
 sub add_file {
     my ($modname, $config, $file) = @_;

-    check_for_file($file, $modname, $modname);
+    check_for_file($config, $file, $modname, $modname);

-    my $mod_dir = File::Spec->catdir('modules', $modname);
+    my $mod_dir = File::Spec->catdir($$config{'mods-dir'}, $modname);

     my $do_add_file = sub {
         my ($type) = @_;
@@ -893,12 +917,12 @@ sub add_file {
         $$config{$type}{$file} = $mod_dir;
     };

-    &$do_add_file(file_type($file));
+    &$do_add_file(file_type($config, $file));
 }

 sub ignore_file {
     my ($modname, $config, $file) = @_;
-    check_for_file($file, undef, $modname);
+    check_for_file($config, $file, undef, $modname);

     my $do_ignore_file = sub {
         my ($type, $ok_if_from) = @_;
@@ -913,19 +937,19 @@ sub ignore_file {
         }
     };

-    &$do_ignore_file(file_type($file));
+    &$do_ignore_file(file_type($config, $file));
 }

 sub check_for_file {
-   my ($file, $added_from, $modname) = @_;
+   my ($config, $file, $added_from, $modname) = @_;

    my $full_path = sub {
        my ($file,$modname) = @_;

-       return File::Spec->catfile('modules', $modname, $file)
+       return File::Spec->catfile($$config{'mods-dir'}, $modname, $file)
            if(defined($modname));

-       my @typeinfo = file_type($file);
+       my @typeinfo = file_type($config, $file);
        return File::Spec->catfile($typeinfo[1], $file);
    };

@@ -1039,15 +1063,15 @@ sub read_info_files {
 #                                                #
 ##################################################
 sub read_info_files {
-    my ($dir, $func) = @_;
+    my ($config, $dir, $func) = @_;

-    $dir = File::Spec->catdir('misc', 'config', $dir);
+    $dir = File::Spec->catdir($$config{'config-dir'}, $dir);

     my %allinfo;
     foreach my $file (dir_list($dir)) {
         my $fullpath = File::Spec->catfile($dir, $file);

-        #trace("reading $fullpath");
+        trace("reading $fullpath");
         %{$allinfo{$file}} = &$func($file, $fullpath);
     }

@@ -1055,13 +1079,15 @@ sub read_module_files {
 }

 sub read_module_files {
-    my ($moddir) = @_;
+    my ($config) = @_;

+    my $mod_dir = $$config{'mods-dir'};
+
     my %allinfo;
-    foreach my $dir (dir_list($moddir)) {
-        my $modfile = File::Spec->catfile($moddir, $dir, 'modinfo.txt');
+    foreach my $dir (dir_list($mod_dir)) {
+        my $modfile = File::Spec->catfile($mod_dir, $dir, 'modinfo.txt');

-        #trace("reading $modfile");
+        trace("reading $modfile");
         %{$allinfo{$dir}} = get_module_info($dir, $modfile);
     }

@@ -1270,8 +1296,9 @@ sub write_pkg_config {

     $$config{'link_to'} = libs('-l', '', 'm', @{$$config{'mod_libs'}});

-    process_template(File::Spec->catfile('misc', 'config', 'botan-config.in'),
-                     'botan-config', $config);
+    process_template(
+       File::Spec->catfile($$config{'config-dir'}, 'botan-config.in'),
+       'botan-config', $config);
     chmod 0755, 'botan-config';

     delete $$config{'link_to'};
@@ -1464,8 +1491,9 @@ sub generate_makefile {
        'install_group' => os_info_for($os, 'install_group'),
        });

-   my $docs = file_list(undef, undef, undef, map_to('doc', @DOCS));
-   $docs .= 'readme.txt';
+   my $docs = file_list(undef, undef, undef,
+                        map_to($$config{'doc-dir'}, @DOCS));
+   $docs .= File::Spec->catfile($$config{'base-dir'}, 'readme.txt');

    my $includes = file_list(undef, undef, undef,
                             map_to($$config{'build_include_botan'},
@@ -1495,7 +1523,7 @@ sub generate_makefile {
        'include_files'   => $includes
        });

-   my $template_dir = File::Spec->catdir('misc', 'config', 'makefile');
+   my $template_dir = File::Spec->catdir($$config{'config-dir'}, 'makefile');
    my $template = undef;

    my $make_style = $$config{'make_style'};
@@ -1547,6 +1575,8 @@ sub guess_cpu_from_this
     $cpu = 'pentium3' if($cpuinfo =~ /pentium 3/);
     $cpu = 'pentium2' if($cpuinfo =~ /pentium 2/);

+    $cpu = 'core2duo' if($cpuinfo =~ /intel\(r\) core\(tm\)2/);
+
     $cpu = 'amd64' if($cpuinfo =~ /athlon64/);
     $cpu = 'amd64' if($cpuinfo =~ /opteron/);

@@ -1623,38 +1653,38 @@ sub guess_triple
             # If guess_cpu_from_this didn't figure it out, try it plain
             if($cpu eq '') { $cpu = lc $uname_p; }

-            my (%SUBMODEL_ALIAS, %ARCH_ALIAS, %ARCH);
+            sub known_arch {
+                my ($name) = @_;

-            foreach my $arch (keys %CPU) {
-                my %info = %{$CPU{$arch}};
+                foreach my $arch (keys %CPU) {
+                    my %info = %{$CPU{$arch}};

-                $ARCH{$arch} = $info{'name'};
-                foreach my $submodel (@{$info{'submodels'}}) {
-                    $ARCH{$submodel} = $info{'name'};
-                }
+                    return 1 if $name eq $info{'name'};
+                    foreach my $submodel (@{$info{'submodels'}}) {
+                        return 1 if $name eq $submodel;
+                    }

-                foreach my $alias (@{$info{'aliases'}}) {
-                    $ARCH_ALIAS{$alias} = $arch;
-                }
+                    foreach my $alias (@{$info{'aliases'}}) {
+                        return 1 if $name eq $alias;
+                    }

-                if(defined($info{'submodel_aliases'})) {
-                    my %submodel_aliases = %{$info{'submodel_aliases'}};
-                    foreach my $sm_alias (keys %submodel_aliases) {
-                        $SUBMODEL_ALIAS{$sm_alias} =
-                            $submodel_aliases{$sm_alias};
+                    if(defined($info{'submodel_aliases'})) {
+                        my %submodel_aliases = %{$info{'submodel_aliases'}};
+                        foreach my $sm_alias (keys %submodel_aliases) {
+                            return 1 if $name eq $sm_alias;
+                        }
                     }
                 }
+                return 0;
             }

-            if(!defined $ARCH{$cpu} && !defined $SUBMODEL_ALIAS{$cpu} &&
-               !defined $ARCH_ALIAS{$cpu})
+            if(!known_arch($cpu))
             {
                 # Nope, couldn't figure out uname -p
                 $cpu = lc `uname -m 2>/dev/null`;
                 chomp $cpu;

-                if(!defined $ARCH{$cpu} && !defined $SUBMODEL_ALIAS{$cpu} &&
-                   !defined $ARCH_ALIAS{$cpu})
+                if(!known_arch($cpu))
                 {
                     $cpu = 'generic';
                 }
============================================================
--- Attic/doc/api.tex	e40b2e58125af2013719a251f78cae6483accc5c
+++ Attic/doc/api.tex	24f0ee532fd3c18d3979a41c2750bf4114ce6402
@@ -12,7 +12,7 @@

 \title{\textbf{Botan API Reference}}
 \author{}
-\date{2006/07/13}
+\date{2006/10/11}

 \newcommand{\filename}[1]{\texttt{#1}}
 \newcommand{\manpage}[2]{\texttt{#1}(#2)}
@@ -25,6 +25,8 @@
 \renewcommand{\arg}[1]{\textsl{#1}}
 \newcommand{\namespace}[1]{\texttt{#1}}

+\newcommand{\url}[1]{\texttt{#1}}
+
 \newcommand{\ie}[0]{\emph{i.e.}}
 \newcommand{\eg}[0]{\emph{e.g.}}

@@ -71,11 +73,13 @@ \subsection{Targets}

 \subsection{Targets}

-Botan's primary targets (system-wise) are 32 and 64-bit systems with at least a
-few megabytes of memory. Generally, given the choice between optimizing for
-32-bit systems and 64-bit systems, Botan chooses 64-bits, simply on the theory
-that where performance really matters (servers), people are using 64-bit
-machines. But performance on 32 bit systems is also quite good.
+Botan's primary targets (system-wise) are 32 and 64-bit systems with
+at least a few megabytes of memory. Generally, given the choice
+between optimizing for 32-bit systems and 64-bit systems, Botan
+chooses 64-bits, simply on the theory that where performance really
+matters (servers), people are using 64-bit machines. And also because
+two of the three machines owned by the primary developer have 64-bit
+CPUs. But performance on 32 bit systems is also quite good.

 Today smaller systems, such as handhelds, set-top boxes, and the
 bigger smart phones and smart cards, are also capable of using
@@ -159,20 +163,34 @@ \section{Initializing the Library}

 \section{Initializing the Library}

-The library needs to have various things done to it in order for it to work
-correctly. To make sure this is done properly, you should create a
-\type{LibraryInitializer} object at the start of your main() function, before
-you start using any part of Botan. The initializer does things like
-initializing the memory allocation system, setting up the algorithm lookup
-tables, finding out if there is a high resolution timer available to use, and
-similar such matters.
+The library needs to have various things done to it in order for it to
+work correctly. To make sure this is done properly, you should create
+a \type{LibraryInitializer} object at the start of your main()
+function, before you start using any part of Botan. The initializer
+does things like initializing the memory allocation system, setting up
+the algorithm lookup tables, finding out if there is a high resolution
+timer available to use, and similar such matters. With no arguments,
+the library is initialized with various default settings. So 99\% of
+the time, all you need is

-The constructor of this object takes a string which specifies any options. If
-more than one is used, they should be separated by a space. Boolean arguments
-(all except for the ``config'' option) can take an argument of ``true'' or
-``false'' to explicitly turn them on or off. Simply giving the name of the
-option without any argument signifies that the option should be toggled on.
+\texttt{Botan::LibraryInitializer init;}

+at the start of your \texttt{main}. If you're not doing anything
+exotic, then you can safely skip the rest of this section.
+
+The constructor takes an instance of another object, called
+\type{InitializerOptions}, which specifies the settings of various
+options. Normally you can ignore this and simply pass a human readable
+string, which the \type{InitializerOptions} constructor will parse. An
+empty string signifies using defaults; any options not specifically
+mentioned in the initialization string also assume the compiled in
+default.
+If more than one option is used, they should be separated by a
+space. Boolean arguments (all except for the ``config'' option) can
+take an argument of ``true'' (or ``yes'') or ``false'' (or ``no'') to
+explicitly turn them on or off. Simply giving the name of the option
+without any argument signifies that the option should be toggled on.
+
 \noindent
 \textbf{Option ``secure\_memory''}: Try to create a more secure allocator type
 -- one that either locks allocated memory into RAM, or that memory maps a disk
@@ -212,27 +230,43 @@ \section{Initializing the Library}
 can occur. Do not use this option.

 \noindent
+\textbf{Option ``fips140''}: This option, in theory, toggles Botan into FIPS
+140 mode. Please note that Botan \emph{has not} been FIPS 140 validated at this
+time, and that a number of changes will be necessary before such a validation
+can occur. Do not use this option.
+
+\noindent
+\textbf{Option ``selftest''}: Run some basic self tests during
+startup.  Specifically this runs a set of tests for DES, TripleDES,
+AES, CMAC(AES), SHA-1, HMAC(SHA-1), SHA-256, and HMAC(SHA-256).
+
+This option, in theory, toggles Botan into FIPS
+140 mode. Please note that Botan \emph{has not} been FIPS 140 validated at this
+time, and that a number of changes will be necessary before such a validation
+can occur. Do not use this option.
+
+\noindent
 \textbf{Option ``seed\_rng''}: Attempt to seed the global PRNGs at
 startup. This option is toggled on by default, and can be disabled by passing
 ``seed\_rng=false''. This is primarily useful when you know that the built-in
 library entropy sources will not work, and you are providing you own entropy
-source(s) with \function{Global\_RNG::add\_es}().
+source(s) later on.

-If you do not create a \type{LibraryInitializer} object, pretty much any Botan
-operation will fail, because it will be unable to do basic things like allocate
-memory or get random bits. Note too, that you should be careful to only create
-one such object.
+If you do not create a \type{LibraryInitializer} object, pretty much
+any Botan operation will fail, because it will be unable to do basic
+things like allocate memory or get random bits. Note too, that you
+should be careful to only create one such object.

-If you wish, you can use a function-based interface to initialize Botan. The
-functions are called \function{initialize} and \function{deinitialize}, and are
-in the \namespace{Init} namespace. In fact, the \type{LibraryInitializer}
-implementation simply calls these functions. The \function{initialize} function
-takes a \type{std::string}, just like \type{LibraryInitializer}'s constructor.
-If you choose to use this interface, you should be very careful to make sure
-that \function{deinitialize} is always called, even in the case of exceptions,
-premature exit or abort, and so on. For this reason using
-\type{LibraryInitializer} is preferred, but there are cases where using it is
-impossible and an interface using plain functions is the only option.
+It is not strictly necessary to create a \type{LibraryInitializer};
+the actual code performing the initialization and shutdown are in
+static member functions of \type{LibraryInitializer}, called
+\function{initialize} and \function{deinitialize}. If you choose to
+use this interface, you should be very careful to make sure that
+\function{deinitialize} is always called, even in the case of
+exceptions, premature exit or abort, and so on. For this reason using
+\type{LibraryInitializer} is preferred, but there are cases where
+using it is impossible and an interface using plain functions is the
+only option.

 \pagebreak

@@ -263,8 +297,7 @@ \section{Gotchas}
 of the library, are creating any memory buffer object that's not a
 \type{SecureVector<byte>} or maybe a \type{MemoryVector<byte>}, you're probably
 doing something wrong (I suppose there may be exceptions to this rule, but not
-many). This is mostly a stylistic point, with an eye toward compatibility with
-future versions.
+many).

 Don't include headers you don't have to. Past experience with Botan has shown
 that headers get renamed fairly regularly as internal design changes are made,
@@ -273,12 +306,14 @@ \section{Gotchas}
 will save you a great deal of pain in this regard, as it insulates you against
 many such changes.

-Use a \function{try}/\function{catch} block inside your \function{main}
-function, and catch any \type{std::exception} throws. This is not strictly
-required, but if you don't, and Botan throws an exception, your application
-will die mysteriously and (probably) without any error message. Some compilers
-provide a useful diagnostic for an uncaught exception, but others simply abort
-the process.
+Use a \function{try}/\function{catch} block inside your
+\function{main} function, and catch any \type{std::exception}
+throws. This is not strictly required, but if you don't, and Botan
+throws an exception, your application will die mysteriously and
+(probably) without any error message. Some compilers provide a useful
+diagnostic for an uncaught exception, but others simply abort the
+process, leaving your (or worse, a user of your application) wondering
+what went wrong.

 \pagebreak

@@ -394,7 +429,7 @@ \subsection{Block Ciphers}
 \subsection{Block Ciphers}

 Block ciphers implement the interface \type{BlockCipher}, found in
-\filename{base.h}.
+\filename{base.h}, as well as the \type{SymmetricAlgorithm} interface.

 \noindent
 \type{void} \function{encrypt}(\type{const byte} \arg{in}[BLOCK\_SIZE],
@@ -403,16 +438,25 @@ \subsection{Block Ciphers}
 \noindent
 \type{void} \function{encrypt}(\type{byte} \arg{block}[BLOCK\_SIZE]) const

-These functions apply the block cipher transformation to \arg{in} and place the
-result in \arg{out}, or encrypts \arg{block} in place (\arg{in} may be the same
-as \arg{out}). BLOCK\_SIZE is a constant member of each class, which specifies
-how much data a block cipher can process at one time. Note that BLOCK\_SIZE is
-not a static class member, like the old BLOCKSIZE was.
+These functions apply the block cipher transformation to \arg{in} and
+place the result in \arg{out}, or encrypts \arg{block} in place
+(\arg{in} may be the same as \arg{out}). BLOCK\_SIZE is a constant
+member of each class, which specifies how much data a block cipher can
+process at one time. Note that BLOCK\_SIZE is not a static class
+member, meaning you can (given a \type{BlockCipher*} named
+\arg{cipher}), call \verb|cipher->BLOCK_SIZE| to get the block size of
+that particular object. \type{BlockCipher}s have similar functions
+\function{decrypt}, which perform the inverse operation.

-\type{BlockCipher}s have similar functions \function{decrypt}, which perform
-the inverse operation.
+\begin{verbatim}
+AES_128 cipher;
+SymmetricKey key(cipher.MAXIMUM_KEYLENGTH); // randomly created
+cipher.set_key(key);

-Block ciphers implement the \type{SymmetricAlgorithm} interface.
+byte in[16] = { /* secrets */ };
+byte out[16];
+cipher.encrypt(in, out);
+\end{verbatim}

 \subsection{Stream Ciphers}

@@ -2969,18 +3013,20 @@ \subsection{Secure Memory}
 various memory locking functions, such as the \function{mlock}(2) call on many
 Unix systems.

-Two of the allocation method used (``malloc'' and ``mmap'') don't require any
-extra privileges on Unix, but locking memory does. At startup, each allocator
-type will attempt to allocate a few blocks (typically totaling 128k), so if you
-want, you can run your application \texttt{setuid} \texttt{root}, and then drop
-privileges immediately after creating your \type{LibraryInitializer}. If you
-end up using more than what's been allocated, some of your sensitive data might
-end up being swappable, but that beats running as \texttt{root} all the
-time. BTW, I would note that, at least on Linux, you can use a kernel module to
-give your process extra privileges (such as the ability to call
-\function{mlock}) without being root. For example, check out my Capability
-Override LSM (\texttt{http://www.randombit.net/projects/cap\_over/}), which
-makes this pretty easy to do.
+Two of the allocation method used (``malloc'' and ``mmap'') don't
+require any extra privileges on Unix, but locking memory does. At
+startup, each allocator type will attempt to allocate a few blocks
+(typically totaling 128k), so if you want, you can run your
+application \texttt{setuid} \texttt{root}, and then drop privileges
+immediately after creating your \type{LibraryInitializer}. If you end
+up using more than what's been allocated, some of your sensitive data
+might end up being swappable, but that beats running as \texttt{root}
+all the time. BTW, I would note that, at least on Linux, you can use a
+kernel module to give your process extra privileges (such as the
+ability to call \function{mlock}) without being root. For example,
+check out my Capability Override LSM
+(\url{http://www.randombit.net/projects/cap\_over/}), which makes this
+pretty easy to do.

 These classes should also be used within your own code for storing sensitive
 data. They are only meant for primitive data types (int, long, etc): if you
@@ -3292,17 +3338,14 @@ \subsection{Efficiency Hints}
 use the classes in \filename{mod\_exp.h}. This stuff is all handled for you by
 the normal high-level interfaces, of course.

-\subsection{A Warning}
+Never use the low-level MPI functions (those that begin with
+\texttt{bigint\_}). These are completely internal to the library, and
+may make arbitrarily strange and undocumented assumptions about their
+inputs, and don't check to see if they are actually true, on the
+assumption that only the library itself calls them, and that the
+library knows what the assumptions are. The interfaces for these
+functions can change completely without notice.

-Don't ever even consider using the low-level MPI functions (those that begin
-with \texttt{bigint\_}). These are completely internal to the library, and make
-arbitrarily strange and undocumented assumptions about their inputs, and don't
-check to see if they are actually true, on the assumption that only the library
-itself calls them, and that the library knows what the assumptions are. The
-interfaces for these functions can change completely without notice. These
-functions aren't visible without effort on your part specifically to that end,
-so you will get no sympathy if you decide to use any of them.
-
 \pagebreak

 \section{Removing Algorithms}
@@ -3375,20 +3418,22 @@ \section{Writing Modules}

 \section{Writing Modules}

-It's a lot simpler to write modules for Botan that it is to write code in the
-core library, for several reasons. First, a module can rely on external
-libraries and services beyond the base ISO C++ libraries, and also machine
-dependent features (assembler, anyone?). Also, the code can be added at
-configuration time on the user's end with very little effort (\ie the code can
-be distributed separately and without depending on patching anything).
+It's a lot simpler to write modules for Botan that it is to write code
+in the core library, for several reasons. First, a module can rely on
+external libraries and services beyond the base ISO C++ libraries, and
+also machine dependent features. Also, the code can be added at
+configuration time on the user's end with very little effort (\ie the
+code can be distributed separately, and included by the user without
+needing to patch any existing source files).

-Creating a module is quite simple. First, there must be a subdirectory in the
-\filename{modules} directory for it. The name of the module is the same as the
-name of this directory. Inside this directory, there needs to be a file, with
-exactly the same name as the directory (that's so the configuration script
-knows where to look). This file contains directives it uses to specify what
-this module does, what systems it runs on, and so on. Comments start with a
-\verb|#| character and continue to end of line.
+Each module lives in a subdirectory of the \filename{modules}
+directory, which exists at the top-level of the Botan source tree. The
+``short name'' of the module is the same as the name of this
+directory. The only required file in this directory is
+\filename{modinfo.txt}, which contains directives that specify what a
+particular module does, what systems it runs on, and so on. Comments
+in \filename{modinfo.txt} start with a \verb|#| character and continue
+to end of line.

 Recognized directives include:

@@ -3402,17 +3447,18 @@ \section{Writing Modules}
    is \texttt{<name>}.}

 \directive{note <note>}{Add a note that will be seen by the end-user at
-configure time.}
+configure time if the module is included into the library.}

-\directive{require\_version <version>}{Require at configure time that the
-version of Botan in use be at least \texttt{<version>}. If not, the module will
-be ignored. Note that this directive is ignored prior to 1.4.3.}
+\directive{require\_version <version>}{Require at configure time that
+the version of Botan in use be at least \texttt{<version>}.}

-\directive{define <macro>}{Define \macro{BOTAN\_EXT\_<macro>} in
-   \filename{config.h}. This may only be used if the module creates
-   user-visible changes. There is a set of conventions that should be followed
-   in deciding what to call this macro (where xxx denotes some descriptive and
-   distinguishing characteristic of the thing implemented, such as
+\directive{define <macro>[,<macro>[,...]]}{Cause the macro
+   \macro{BOTAN\_EXT\_<macro>} (for each instance of \macro{<macro>}
+   in the directive) to be defined in \filename{build.h}. This should
+   only be used if the module creates user-visible changes. There is a
+   set of conventions that should be followed in deciding what to call
+   this macro (where xxx denotes some descriptive and distinguishing
+   characteristic of the thing implemented, such as
    \macro{ALLOC\_MLOCK} or \macro{MUTEX\_PTHREAD}):

 \begin{itemize}
@@ -3425,30 +3471,28 @@ \section{Writing Modules}
 \end{itemize}
 }

-\directive{<lib> / </lib>}{This specifies any extra libraries to be linked in.
-It is a mapping from OS to library name, for example \texttt{linux -> rt},
-which means that on Linux librt should be linked in. You can also use ``all''
-to force the library to be linked in on all systems.}
+\directive{<libs> / </libs>}{This specifies any extra libraries to be
+linked in.  It is a mapping from OS to library name, for example
+\texttt{linux -> rt}, which means that on Linux librt should be linked
+in. You can also use ``all'' to force the library to be linked in on
+all systems.}

-\directive{add\_file <file>}{Tell the configuration script to add the file
-   given into the source tree. This file must exist in the module directory.}
+\directive{<add> / </add>}{Tell the configuration script to add the
+   files named between these two tags into the source tree. All these
+   files must exist in the current module directory.}

-\directive{ignore\_file <file>}{Tell the configuration script to ignore the
-   file given in the main source tree.}
+\directive{<ignore> / </ignore>}{Tell the configuration script to
+   ignore the files named in the main source tree. This is useful, for
+   example, when replacing a C++ implementation with a pure assembly
+   version.}

-\directive{replace\_file <file>}{Tell the configuration script to ignore the
-   file given in the main source tree, and instead use the one in the module's
-   directory.}
+\directive{<replace> / </replace>}{Tell the configuration script to
+   ignore the file given in the main source tree, and instead use the
+   one in the module's directory.}

-\directive{local\_only <file>}{Mark this header file as being for the build
-   only; it will not be installed. This is useful for headers used internally
-   that are not exposed to the client.}
+Additionally, the module file can contain blocks, delimited by the
+following pairs:

-\vskip 10pt
-\noindent
-Additionally, the module file can contain blocks, delimited by
-the following pairs:
-
 \texttt{<os> / </os>}, \texttt{<arch> / </arch>}, \texttt{<cc> / </cc>}

 \noindent
@@ -3456,10 +3500,6 @@ \section{Writing Modules}
 make the configuration script only allow the module to be compiled on those
 architectures. Not having a block means any value is acceptable.

-\section{Writing BigInt assembly modules}
-
-Write me...
-
 \pagebreak

 \section{Compliance with Standards}
@@ -3537,28 +3577,30 @@ \section{Algorithms Listing}

 \section{Algorithms Listing}

-Botan includes a very sizable number of cryptographic algorithms. In nearly all
-cases, you never need to know the header file or type name to use
-them. However, you do need to know what string (or strings) are used to
-identify that algorithm. Generally, these names conform to those set out by
-SCAN (Standard Cryptographic Algorithm Naming), which is a document which
-specifies how strings are mapped onto algorithm objects, which is useful for a
-wide variety of crypto APIs (SCAN is oriented towards Java, but Botan and
-several other non-Java libraries also make at least some use of it). For full
-details, read the SCAN document, which can be found at
-\textbf{http://www.users.zetnet.co.uk/hopwood/crypto/scan/}
+Botan includes a very sizable number of cryptographic algorithms. In
+nearly all cases, you never need to know the header file or type name
+to use them. However, you do need to know what string (or strings) are
+used to identify that algorithm. Generally, these names conform to
+those set out by SCAN (Standard Cryptographic Algorithm Naming), which
+is a document which specifies how strings are mapped onto algorithm
+objects, which is useful for a wide variety of crypto APIs (SCAN is
+oriented towards Java, but Botan and several other non-Java libraries
+also make at least some use of it). For full details, read the SCAN
+document, which can be found at
+\url{http://www.users.zetnet.co.uk/hopwood/crypto/scan/}

-Many of these algorithms can take options (such as the number of rounds in a
-block cipher, the output size of a hash function, etc). These are shown in the
-following list; all of them default to reasonable values (unless otherwise
-marked). There are algorithm-specific limits on most of them. When you see
-something like ``HASH'' or ``BLOCK'', that means you should insert the name of
-some algorithm of that type. There are no defaults for those options.
+Many of these algorithms can take options (such as the number of
+rounds in a block cipher, the output size of a hash function,
+etc). These are shown in the following list; all of them default to
+reasonable values (unless otherwise marked). There are
+algorithm-specific limits on most of them. When you see something like
+``HASH'' or ``BLOCK'', that means you should insert the name of some
+algorithm of that type. There are no defaults for those options.

-A few very obscure algorithms are skipped; if you need one of them, you'll know
-it, and you can look in the appropriate header to see what that classes'
-\function{name} function returns (the names tend to match that in SCAN, if it's
-defined there).
+A few very obscure algorithms are skipped; if you need one of them,
+you'll know it, and you can look in the appropriate header to see what
+that classes' \function{name} function returns (the names tend to
+match that in SCAN, if it's defined there).

 \begin{list}{$\cdot$}
   \item ROUNDS: The number of rounds in a block cipher.
@@ -3570,10 +3612,11 @@ \section{Algorithms Listing}

 \vskip .05in
 \noindent
-\textbf{Block Ciphers:} ``AES'', ``Blowfish'', ``CAST-128'', ``CAST-256'',
-``DES'', ``DESX'', ``TripleDES'', ``GOST'', ``IDEA'', ``MARS'',
-``MISTY1(ROUNDS)'', ``RC2'', ``RC5(ROUNDS)'', ``RC6'', ``SAFER-SK(ROUNDS)'',
-``SEED'', ``Serpent'', ``Skipjack'', ``SQUARE'', ``TEA'', ``Twofish'', ``XTEA''
+\textbf{Block Ciphers:} ``AES'', ``Blowfish'', ``CAST-128'',
+``CAST-256'', ``DES'', ``DESX'', ``TripleDES'', ``GOST'', ``IDEA'',
+``MARS'', ``MISTY1(ROUNDS)'', ``RC2'', ``RC5(ROUNDS)'', ``RC6'',
+``SAFER-SK(ROUNDS)'', ``SEED'', ``Serpent'', ``Skipjack'', ``Square'',
+``TEA'', ``Twofish'', ``XTEA''

 \noindent
 \textbf{Stream Ciphers:} ``ARC4'', ``MARK4'', ``Turing'', ``WiderWake4+1-BE''
@@ -3588,17 +3631,8 @@ \section{Algorithms Listing}

 \pagebreak

-\section{More Information}
+\section{Support and Further Information}

-\subsection{Support}
-
-Questions or problems you have with Botan can be directed to the development
-mailing list (currently called \texttt{opencl-devel}). Joining this list is
-highly recommended if you're going to be using Botan, since often advance
-notice of upcoming changes is sent there. ``Philosophical'' bug reports,
-announcements of programs using Botan, and basically anything else having to do
-with Botan are also welcome.
-
 \subsection{Compatibility}

 Generally, cryptographic algorithms are well standardized, and thus
@@ -3628,12 +3662,12 @@ \subsection{Patents}
 any algorithm you are considering using in an application, please discuss it
 with your attorney.

-\subsection{Further Reading and Information}
+\subsection{Recommended Reading}

-It's a very good idea if you have some knowledge of cryptography prior to
-trying to use this stuff. You really should read one or more of these books
-before seriously using the library (note that the Handbook of Applied
-Cryptography is available online, and I highly recommend you read it):
+It's a very good idea if you have some knowledge of cryptography prior
+to trying to use this stuff. You really should read one or more of
+these books before seriously using the library (note that the Handbook
+of Applied Cryptography is available for free online):

 \setlength{\parskip}{5pt}

@@ -3656,8 +3690,18 @@ \subsection{Further Reading and Informat
 at: IEEE 1363 and 1363a, SCAN, NESSIE, PKCS \#1 v2.1, the security related FIPS
 documents, and the CFRG RFCs.

-\pagebreak
+\subsection{Support}

+Questions or problems you have with Botan can be directed to the
+development mailing list. Joining this list is highly recommended if
+you're going to be using Botan, since often advance notice of upcoming
+changes is sent there. ``Philosophical'' bug reports, announcements of
+programs using Botan, and basically anything else having to do with
+Botan are also welcome.
+
+The lists can be found at
+\url{http://www.randombit.net/mailman/listinfo/}.
+
 \subsection{Contact Information}

 A PGP key with a fingerprint of
@@ -3665,25 +3709,20 @@ \subsection{Contact Information}
 Botan releases. This key can be found in the file \filename{doc/pgpkeys.asc};
 PGP keys for the developers are also stored there.

-Another key, with fingerprint
-\verb|33E3 9768 1D13 E7B4 1A01 BBCE A63F 2CBD FA02 FBCC|, was used for signing
-releases up to version 1.4.2. This key has been retired.
-
 \vskip 5pt \noindent
-Web Site: \verb|http://botan.randombit.net|
+Web Site: \url{http://botan.randombit.net}

 \vskip 5pt \noindent
-Mailing lists: \verb|http://www.randombit.net/mailman/|
+Mailing lists: \url{http://www.randombit.net/mailman/}

-\pagebreak
+\subsection{License}

-\section{License}
-
 Copyright \copyright  2000-2006, The Botan Project

-This work is licensed under the Creative Commons Attribution-ShareAlike 2.5
-License. To view a copy of this license, visit
-http://creativecommons.org/licenses/by-sa/2.5/ or send a letter to Creative
-Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.
+This work is licensed under the Creative Commons
+Attribution-ShareAlike 2.5 License. To view a copy of this license,
+visit \url{http://creativecommons.org/licenses/by-sa/2.5/} or send a
+letter to Creative Commons, 543 Howard Street, 5th Floor, San
+Francisco, California, 94105, USA.

 \end{document}
============================================================
--- Attic/doc/building.tex	0cecc39c901fed7f95687dd9be9f15bedd175448
+++ Attic/doc/building.tex	766f68650552872ddafc3091e70990ecf7e3892b
@@ -33,13 +33,13 @@ \section{Introduction}

 \section{Introduction}

-This document describes how to build Botan on Unix/POSIX and MS Windows
-systems. The POSIX oriented descriptions should apply to most common Unix
-systems today (including MacOS X), along with POSIX-ish systems like BeOS, QNX,
-and Plan 9.  Currently, systems other than Windows and POSIX (for example, VMS,
-MacOS 9, and OS/390) are not supported by the build system, primarily due to
-lack of access. Please contact the maintainer if you would like to build Botan
-on such a system.
+This document describes how to build Botan on Unix/POSIX and MS
+Windows systems. The POSIX oriented descriptions should apply to most
+common Unix systems (including MacOS X), along with POSIX-ish systems
+like BeOS, QNX, and Plan 9. Currently, systems other than Windows and
+POSIX (such as VMS, MacOS 9, OS/390, OS/400, ...) are not supported by
+the build system, primarily due to lack of access. Please contact the
+maintainer if you would like to build Botan on such a system.

 \section{For the Impatient}

@@ -49,19 +49,26 @@ \section{For the Impatient}
 $ make install
 \end{verbatim}

-Or \verb|nmake|, if you're compiling on Windows with Visual C++. The
-autoconfiguaration abilities of \filename{configure.pl} were only recently
+Or using \verb|nmake|, if you're compiling on Windows with Visual
+C++. On platforms that do not understand the '\#!' convention for
+beginning script files, or that have Perl installed in an unusual
+spot, you might need to prefix the \texttt{configure.pl} command with
+\texttt{perl} or \texttt{/path/to/perl}.
+
+The autoconfiguaration abilities of \filename{configure.pl} were only recently
 added, so they may break if you run it on something unusual. In addition, you
 are certain to get more features, and possibly better optimization, by
 explicitly specifying how you want to library configured. How to do this is
-detailed below.
+detailed below. Also, if you don't want to use the default compiler (typically
+either GNU C++ or Visual C++, depending on the platform), you will need to
+specify one.

 \section{Building the Library}

 The first step is to run \filename{configure.pl}, which is a Perl script that
 creates various directories, config files, and a Makefile for building
 everything. It is run as \verb|./configure.pl CC-OS-CPU <extra args>|. The
-script requires at least Perl 5.005, and preferably 5.6 or higher.
+script requires at least Perl 5.6; any later version should also work.

 The tuple CC-OS-CPU specifies what system Botan is being built for, in terms of
 the C++ compiler, the operating system, and the CPU model. For example, to use
@@ -71,25 +78,25 @@ \section{Building the Library}
 and \verb|CPU| that \filename{configure.pl} supports, run it with the
 ``\verb|--help|'' option.

-You can put basically anything reasonable for CPU: the script knows about a
-large number of different architectures, their sub-models, and common aliases
-for them. The script does not display all the possibilities in it's help
-message because there are simply too many entries (if you're curious about what
-exactly is available, you can look at the \verb|%ARCH|, \verb|%ARCH_ALIAS|, and
-\verb|%SUBMODEL_ALIAS| hashes at the start of the script). You should only
-select the 64-bit version of a CPU (like ``sparc64'' or ``mips64'') if your
-operating system knows how to handle 64-bit object code -- a 32-bit kernel on a
-64-bit CPU will generally not like 64-bit code. For example,
-gcc-solaris-sparc64 will not work unless you're running a 64-bit Solaris kernel
-(for 32-bit Solaris running on an UltraSPARC system, you want
-gcc-solaris-sparc32-v9). You may or may not have to install 64-bit versions of
-libc and related system libraries as well.
+You can put basically anything reasonable for CPU: the script knows
+about a large number of different architectures, their sub-models, and
+common aliases for them. The script does not display all the
+possibilities in its help message because there are simply too many
+entries. You should only select the 64-bit version of a CPU (such as
+``sparc64'' or ``mips64'') if your operating system knows how to
+handle 64-bit object code -- a 32-bit kernel on a 64-bit CPU will
+generally not like 64-bit code. For example, gcc-solaris-sparc64 will
+not work unless you're running a 64-bit Solaris kernel (for 32-bit
+Solaris running on an UltraSPARC system, you want
+gcc-solaris-sparc32-v9). You may or may not have to install 64-bit
+versions of libc and related system libraries as well.

-The script also knows about the various extension modules available. You can
-enable one or more with the option ``\verb|--modules=MOD|'', where \verb|MOD|
-is some name that identifies the extension (or a comma separated list of
-them). Modules provide additional capabilities which require the use of non
-portable APIs.
+The script also knows about the various extension modules
+available. You can enable one or more with the option
+``\verb|--modules=MOD|'', where \verb|MOD| is some name that
+identifies the extension (or a comma separated list of them). Modules
+provide additional capabilities which require the use of APIs not
+provided by ISO C/C++.

 Not all OSes or CPUs have specific support in \filename{configure.pl}. If the
 CPU architecture of your system isn't supported by \filename{configure.pl}, use
@@ -97,22 +104,22 @@ \section{Building the Library}
 flags. Similarly, setting OS to 'generic' disables things which depend greatly
 on OS support (specifically, shared libraries).

-However, it's impossible to guess which options to give to a system compiler.
-Thus, if you want to compile Botan with a compiler which
-\filename{configure.pl} does not support, the script will have to be updated.
-Preferably, mail the man pages (or similar documentation) for the C and C++
-compilers and the system linker to the author, or download the Botan-config
-package from the Botan web site, and do it yourself. Modifying
-\filename{configure.pl} on it's own is useless aside from one-off hacks,
-because the script is auto-generated by \emph{another} Perl script, which reads
-a little mini-language that tells it all about the systems in question.
+However, it's impossible to guess which options to give to a system
+compiler.  Thus, if you want to compile Botan with a compiler which
+\filename{configure.pl} does not support, you will need to tell it how
+that compiler works. This is done by adding a new file in the
+directory \filename{misc/config/cc}; the existing files should put you
+in the right direction.

-The script tries to guess what kind of makefile to generate, and it almost
-always guesses correctly (basically, Visual C++ uses NMAKE with Windows
-commands, and everything else uses POSIX make with POSIX commands). Just in
-case, you can override it with \verb|--make-style=somestyle|. The styles Botan
-currently knows about are 'unix' (normal Unix makefiles), and 'nmake', the make
-variant commonly used by Windows compilers.
+The script tries to guess what kind of makefile to generate, and it
+almost always guesses correctly (basically, Visual C++ uses NMAKE with
+Windows commands, and everything else uses Unix make with POSIX
+commands). Just in case, you can override it with
+\verb|--make-style=somestyle|. The styles Botan currently knows about
+are 'unix' (normal Unix makefiles), and 'nmake', the make variant
+commonly used by Windows compilers. To add a new variant (eg, a build
+script for VMS), you will need to create a new template file in
+\filename{misc/config/makefile}.

 \pagebreak

@@ -206,15 +213,15 @@ \subsection{Configuration Parameters}
 example, if \verb|BOTAN_EXT_COMPRESSOR_BZIP2| is defined, then an application
 using Botan can include \filename{<botan/bzip2.h>} and use the Bzip2 filters.

-\macro{BOTAN\_MP\_WORD\_BITS}: This macro controls the size of the words used
-for calculations with the MPI implementation in Botan. You can choose 8, 16,
-32, or 64, with 32 being the default.  You can use 8, 16, or 32 bit words on
-any CPU, but the value should be set to the same size as the CPU's registers
-for best performance. You can only use 64-bit words if the \module{mp\_asm64}
-module is used; this offers vastly improved performance of public key
-algorithms on certain 64-bit CPUs - this is set by default if the module is
-used. Unless you are building for a 8 or 16-bit CPU, probably this isn't worth
-messing with.
+\macro{BOTAN\_MP\_WORD\_BITS}: This macro controls the size of the
+words used for calculations with the MPI implementation in Botan. You
+can choose 8, 16, 32, or 64, with 32 being the default. You can use 8,
+16, or 32 bit words on any CPU, but the value should be set to the
+same size as the CPU's registers for best performance. You can only
+use 64-bit words if an assembly module (such as \module{mp\_ia32} or
+\module{mp\_asm64}) is used. If the appropriate module is available,
+64 bits are used, otherwise this is set to 32. Unless you are building
+for a 8 or 16-bit CPU, this isn't worth messing with.

 \macro{BOTAN\_VECTOR\_OVER\_ALLOCATE}: The memory container
 \type{SecureVector} will over-allocate requests by this amount (in
@@ -232,16 +239,25 @@ \subsection{Configuration Parameters}
 compressing. The default is 255, which means 'Unknown'. You can look in RFC
 1952 for the full list; the most common are Windows (0) and Unix (3). There is
 also a Macintosh (7), but it probably makes more sense to use the Unix code on
-OS X. This is only used if the \texttt{comp\_zlib} module (which includes a
-gzip compressor) is built.
+OS X.

 \pagebreak

+\subsection{Multiple Builds}
+
+It may be useful to run multiple builds
+
+\subsection{Local Configuration}
+
+
+
+\pagebreak
+
 \section{Modules}

-There are a fairly large number of modules included with Botan. Some of these
-are extremely useful, while others are only necessary in very unusual
-circumstances. The modules included with this release are:
+There are a fairly large number of modules included with Botan. Some
+of these are extremely useful, while others are only necessary in very
+unusual circumstances. The modules included with this release are:

 \newcommand{\mod}[2]{\textbf{#1}: #2}

============================================================
--- Attic/misc/config/arch/amd64	4a8ddf11d915fb90de3fdf9800d6080c83640c8b
+++ Attic/misc/config/arch/amd64	3bda1ee7f9267f5af7c95766e9eee95c7e5dbb5d
@@ -9,4 +9,5 @@ em64t
 athlon64
 opteron
 em64t
+core2duo
 </aliases>
============================================================
--- Attic/misc/config/buildh.in	75037518b4a690490e86271ef2397b64661b892d
+++ Attic/misc/config/buildh.in	f390f744fb5b88b61bf08eec18e047d5b5122d35
@@ -1,5 +1,5 @@
 /*************************************************
-* Build Config Header File                       *
+* Build Configuration Header File                *
 * (C) 1999-2006 The Botan Project                *
 *************************************************/

============================================================
--- Attic/misc/config/cc/gcc	141963a58d991c8890197a0a1ac06befb785eb23
+++ Attic/misc/config/cc/gcc	b8325689146701fd42f035c20d39185cdc5772a6
@@ -32,12 +32,9 @@ beos    -> "ld -shared -h $(SONAME)"
 beos    -> "ld -shared -h $(SONAME)"
 </so_link_flags>

-# Using -momit-leaf-frame-pointer would be a huge win (on x86 anyway, why isn't
-# it implemented elsewhere?), but it was added in 3.0 and the current mandate
-# is to continue to support 2.95.x, so we don't use it (yet).
 <mach_opt>
 # Specializations first (they don't need to be, just clearer)
-i386           -> "-mcpu=i686"
+i386           -> "-mcpu=i686 -momit-leaf-frame-pointer"
 r10000         -> "-mips4"
 alpha-ev67     -> "-mcpu=ev6" # FIXME: GCC 3.1 and on has -march=ev67
 alpha-ev68     -> "-mcpu=ev6"
@@ -49,9 +46,9 @@ alpha     -> "-mcpu=SUBMODEL" alpha-
 # Anything after the quotes is what should be *removed* from the submodel name
 # before it's put into SUBMODEL.
 alpha     -> "-mcpu=SUBMODEL" alpha-
-amd64     -> ""
+amd64     -> "-momit-leaf-frame-pointer"
 arm       -> "-mcpu=SUBMODEL"
-ia32      -> "-march=SUBMODEL"
+ia32      -> "-march=SUBMODEL -momit-leaf-frame-pointer"
 ia64      -> "-mtune=SUBMODEL"
 hppa      -> "-march=SUBMODEL" hppa
 m68k      -> "-mSUBMODEL"
============================================================
--- Attic/misc/python/src/core.cpp	1e92d8a2a89f4f0abcf33b0981ff47fb5bf45347
+++ Attic/misc/python/src/core.cpp	54a44c78ed3d2ad69cbae4ae7782fb0b78483e0c
@@ -9,7 +9,10 @@ namespace python = boost::python;
 #include <boost/python.hpp>
 namespace python = boost::python;

-extern void export_basic_algos();
+extern void export_block_ciphers();
+extern void export_stream_ciphers();
+extern void export_hash_functions();
+extern void export_macs();
 extern void export_filters();
 extern void export_pk();
 extern void export_x509();
@@ -29,7 +32,11 @@ BOOST_PYTHON_MODULE(_botan)
       .value("encryption", ENCRYPTION)
       .value("decryption", DECRYPTION);

-   export_basic_algos();
+   export_block_ciphers();
+   export_stream_ciphers();
+   export_hash_functions();
+   export_macs();
+
    export_filters();
    export_pk();
    export_x509();
============================================================
--- Attic/misc/python/src/algos.cpp	89ffde42ff0a3beecf9f0bee33c765a5ae8a699e
+++ Attic/misc/python/src/macs.cpp	8ba2a2fc0503648e27ebce9e19aa8b54d063bd81
@@ -9,38 +9,6 @@ namespace python = boost::python;
 #include <boost/python.hpp>
 namespace python = boost::python;

-class Py_StreamCipher
-   {
-   public:
-      u32bit keylength_min() const { return cipher->MINIMUM_KEYLENGTH; }
-      u32bit keylength_max() const { return cipher->MAXIMUM_KEYLENGTH; }
-      u32bit keylength_mod() const { return cipher->KEYLENGTH_MULTIPLE; }
-
-      void set_key(const OctetString& key) { cipher->set_key(key); }
-      bool valid_keylength(u32bit kl) const
-         {
-         return cipher->valid_keylength(kl);
-         }
-
-      std::string name() const { return cipher->name(); }
-      void clear() throw() { cipher->clear(); }
-
-      std::string crypt(const std::string& in) const
-         {
-         SecureVector<byte> out(in.size());
-         cipher->encrypt((const byte*)in.data(), out.begin(), in.size());
-         return std::string((const char*)out.begin(), out.size());
-         }
-
-      Py_StreamCipher(const std::string& name)
-         {
-         cipher = get_stream_cipher(name);
-         }
-      ~Py_StreamCipher() { delete cipher; }
-   private:
-      StreamCipher* cipher;
-   };
-
 class Py_MAC
    {
    public:
@@ -75,24 +43,8 @@ class Py_MAC
       MessageAuthenticationCode* mac;
    };

-extern void export_block_ciphers();
-extern void export_hash_functions();
-
-void export_basic_algos()
+void export_macs()
    {
-   export_block_ciphers();
-   export_hash_functions();
-
-   python::class_<Py_StreamCipher>("StreamCipher", python::init<std::string>())
-      .add_property("keylength_min", &Py_StreamCipher::keylength_min)
-      .add_property("keylength_max", &Py_StreamCipher::keylength_max)
-      .add_property("keylength_mod", &Py_StreamCipher::keylength_mod)
-      .add_property("name", &Py_StreamCipher::name)
-      .def("clear", &Py_StreamCipher::clear)
-      .def("valid_keylength", &Py_StreamCipher::valid_keylength)
-      .def("set_key", &Py_StreamCipher::set_key)
-      .def("crypt", &Py_StreamCipher::crypt);
-
    python::class_<Py_MAC>("MAC", python::init<std::string>())
       .add_property("output_length", &Py_MAC::output_length)
       .add_property("keylength_min", &Py_MAC::keylength_min)
============================================================
--- Attic/misc/python/src/pk.cpp	c72e2ba3d2d906d909de4b9cf5e684517a8eb134
+++ Attic/misc/python/src/pk.cpp	403f3e48978c042df5bf23a1d3036bedef7d651f
@@ -12,38 +12,70 @@ namespace python = boost::python;
 #include <boost/python.hpp>
 namespace python = boost::python;

-std::string DER_encode_str(const X509_PublicKey* key)
+std::string encode_pub(const Public_Key* key,
+                       const std::string& type)
    {
-   Pipe pipe;
-   X509::encode(*key, pipe, RAW_BER);
-   return pipe.read_all_as_string();
+   if(type == "DER")
+      {
+      Pipe pipe;
+      pipe.start_msg();
+      X509::encode(*key, pipe, RAW_BER);
+      pipe.end_msg();
+      return pipe.read_all_as_string();
+      }
+   else if(type == "PEM")
+      return X509::PEM_encode(*key);
+   else
+      throw Encoding_Error("Unknown key encoding method " + type);
    }

-std::string get_oid_str(const X509_PublicKey* key)
+std::string encode_priv(const Private_Key* key,
+                        const std::string& type)
    {
-   try
+   if(type == "DER")
       {
-      return key->get_oid().as_string();
+      Pipe pipe;
+      PKCS8::encode(*key, pipe, RAW_BER);
+      return pipe.read_all_as_string();
       }
-   catch(Lookup_Error)
-      {
-      return "";
-      }
+   else if(type == "PEM")
+      return PKCS8::PEM_encode(*key);
+   else
+      throw Encoding_Error("Unknown key encoding method " + type);
    }

-X509_PublicKey* load_key_str(const std::string& file)
+Private_Key* load_priv(const std::string& file, const std::string& pass)
    {
+   return PKCS8::load_key(file, pass);
+   }
+
+Public_Key* load_public(const std::string& file)
+   {
    return X509::load_key(file);
    }

 void export_pk()
    {
-   python::class_<X509_PublicKey, boost::noncopyable>
-      ("X509_PublicKey", python::no_init)
-      .def("__init__", python::make_constructor(load_key_str))
-      .add_property("algo", &X509_PublicKey::algo_name)
-      .add_property("max_input_bits", &X509_PublicKey::max_input_bits)
-      .add_property("oid", &get_oid_str)
-      .def("__str__", &X509::PEM_encode)
-      .def("der_encode", &DER_encode_str);
+   python::class_<Public_Key, boost::noncopyable>
+      ("Public_Key", python::no_init)
+      .add_property("name", &Public_Key::algo_name)
+      .add_property("max_input_bits", &Public_Key::max_input_bits)
+      .def("public_key", encode_pub);
+
+   python::class_<Private_Key, python::bases<Public_Key>, boost::noncopyable>
+      ("Private_Key", python::no_init)
+      .def("private_key", encode_priv);
+
+   python::def("private_key", load_priv,
+               python::return_value_policy<python::manage_new_object>());
+   python::def("public_key", load_public,
+               python::return_value_policy<python::manage_new_object>());
+
+   python::class_<RSA_PublicKey, python::bases<Public_Key> >
+      ("RSA_PublicKey", python::no_init);
+   python::class_<DSA_PublicKey, python::bases<Public_Key> >
+      ("DSA_PublicKey", python::no_init);
+
+   python::class_<RSA_PrivateKey, python::bases<RSA_PublicKey, Private_Key> >
+      ("RSA_PrivateKey", python::init<u32bit>());
    }
============================================================
--- Attic/modules/alg_ia32/asm_macr.h	b9f54c5c1ebf73c1f0e3a2e19636420112428164
+++ Attic/modules/alg_ia32/asm_macr.h	c8ddcf00f92a14abe6b9c72b86ee4d04bfe489a0
@@ -99,15 +99,13 @@ func_name:
 #define IMM(VAL) $VAL

 #define ADD(TO, FROM) addl FROM, TO
-#define ADD_IMM(TO, NUM) addl IMM(NUM), 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 CLEAR_CARRY() clc
-
 #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
============================================================
--- Attic/modules/alg_ia32/mp_muladd.S	f47fec487fb0622e334c90cb71be2c43b1656389
+++ Attic/modules/alg_ia32/mp_muladd.S	d6ce402b02bb7d1751edc8119bc82fd8629be504
@@ -11,11 +11,13 @@ START_FUNCTION(bigint_mul_add_words)
    SPILL_REGS()
 #define PUSHED 4

-   ASSIGN(EBX, ARG(2)) /* x[] */
+#define LOOP_CTR ESI
+   ASSIGN(LOOP_CTR, ARG(3)) /* x_size */
+   ZEROIZE(EDI)
+
    ASSIGN(ECX, ARG(1)) /* z[] */
-   ASSIGN(ESI, ARG(3)) /* x_size */
+   ASSIGN(EBX, ARG(2)) /* x[] */
    ASSIGN(EBP, ARG(4)) /* y */
-   ZEROIZE(EDI)

 #define MULADD_OP(N)                       \
    ASSIGN(EAX, ARRAY4(EBX, N))           ; \
@@ -24,8 +26,8 @@ START_FUNCTION(bigint_mul_add_words)
    ASSIGN(EDI, EDX)                      ; \
    ADD_W_CARRY(ARRAY4(ECX, N), EDI, EAX) ;

-   JUMP_IF_ZERO(ESI, .MUL_ADD_DONE)
-   JUMP_IF_LT(ESI, 8, .MULADD1_LOOP)
+   JUMP_IF_ZERO(LOOP_CTR, .MUL_ADD_DONE)
+   JUMP_IF_LT(LOOP_CTR, 8, .MULADD1_LOOP)

 START_LOOP(.MULADD8)
    MULADD_OP(0)
@@ -37,20 +39,20 @@ START_LOOP(.MULADD8)
    MULADD_OP(6)
    MULADD_OP(7)

-   SUB_IMM(ESI, 8)
+   SUB_IMM(LOOP_CTR, 8)
    ADD_IMM(EBX, 32)
    ADD_IMM(ECX, 32)
-LOOP_UNTIL_LT(ESI, 8, .MULADD8)
+LOOP_UNTIL_LT(LOOP_CTR, 8, .MULADD8)

-   JUMP_IF_ZERO(ESI, .MUL_ADD_DONE)
+   JUMP_IF_ZERO(LOOP_CTR, .MUL_ADD_DONE)

 START_LOOP(.MULADD1)
    MULADD_OP(0)

-   SUB_IMM(ESI, 1)
+   SUB_IMM(LOOP_CTR, 1)
    ADD_IMM(EBX, 4)
    ADD_IMM(ECX, 4)
-LOOP_UNTIL_EQ(ESI, 0, .MULADD1)
+LOOP_UNTIL_EQ(LOOP_CTR, 0, .MULADD1)

 .MUL_ADD_DONE:

============================================================
--- Attic/modules/eng_aep/modinfo.txt	b84fbf8d0855e1d4d84fe1d2f2ced1032798b5a0
+++ Attic/modules/eng_aep/modinfo.txt	579ec293b81755160084c68cf57d17978f851745
@@ -12,8 +12,7 @@
 aep_conn.h
 </add>

-define ENGINE_AEP
-define ENTROPY_SRC_AEP
+define ENGINE_AEP,ENTROPY_SRC_AEP

 <libs>
 all -> aep
============================================================
--- emsa1.cpp	1dd0e80f0dc5bfbd718e2edc2e6de80fa482b50c
+++ emsa1.cpp	e12d485d4f2484e6b53cd52288486cb56419b26c
@@ -31,7 +31,7 @@ SecureVector<byte> EMSA1::encoding_of(co
                                       u32bit output_bits)
    {
    if(msg.size() != hash->OUTPUT_LENGTH)
-      throw Invalid_Argument("EMSA1::encoding_of: Invalid size for input");
+      throw Encoding_Error("EMSA1::encoding_of: Invalid size for input");
    if(8*msg.size() <= output_bits)
       return msg;

============================================================
--- emsa2.cpp	a4d8301f23805ba4bb2554591dfc20e373bce4ca
+++ emsa2.cpp	39f86a2ed053f0ddb8a0e0fb032ea9007149d27b
@@ -34,9 +34,9 @@ SecureVector<byte> EMSA2::encoding_of(co
    u32bit output_length = (output_bits + 1) / 8;

    if(msg.size() != hash->OUTPUT_LENGTH)
-      throw Invalid_Argument("EMSA2::encoding_of: Bad input length");
+      throw Encoding_Error("EMSA2::encoding_of: Bad input length");
    if(output_length < hash->OUTPUT_LENGTH + 4)
-      throw Invalid_Argument("EMSA2::encoding_of: Output length is too small");
+      throw Encoding_Error("EMSA2::encoding_of: Output length is too small");

    bool empty = true;
    for(u32bit j = 0; j != hash->OUTPUT_LENGTH; ++j)
@@ -62,7 +62,7 @@ EMSA2::EMSA2(const std::string& hash_nam
    {
    hash_id = ieee1363_hash_id(hash_name);
    if(hash_id == 0)
-      throw Invalid_Argument("EMSA2 cannot be used with " + hash->name());
+      throw Encoding_Error("EMSA2 cannot be used with " + hash->name());
    hash = get_hash(hash_name);
    empty_hash = hash->final();
    }
============================================================
--- emsa3.cpp	367b509f38995bb4978b8f514239c97989fb63b3
+++ emsa3.cpp	0712cedbf4b4da5381aa6ec751798e527bac5239
@@ -32,11 +32,11 @@ SecureVector<byte> EMSA3::encoding_of(co
                                       u32bit output_bits)
    {
    if(msg.size() != hash->OUTPUT_LENGTH)
-      throw Invalid_Argument("EMSA3::encoding_of: Bad input length");
+      throw Encoding_Error("EMSA3::encoding_of: Bad input length");

    u32bit output_length = output_bits / 8;
    if(output_length < hash_id.size() + hash->OUTPUT_LENGTH + 10)
-      throw Invalid_Argument("EMSA3::pad: Output length is too small");
+      throw Encoding_Error("EMSA3::pad: Output length is too small");

    SecureVector<byte> T(output_length);
    const u32bit P_LENGTH = output_length - hash->OUTPUT_LENGTH -
============================================================
--- emsa4.cpp	a45dd0f15cdb2cb8f81d8493b44248f206bf44f2
+++ emsa4.cpp	37c2f6432f8c13d345aedd7e5155aa3f4fb75e39
@@ -36,9 +36,9 @@ SecureVector<byte> EMSA4::encoding_of(co
    const u32bit HASH_SIZE = hash->OUTPUT_LENGTH;

    if(msg.size() != HASH_SIZE)
-      throw Invalid_Argument("EMSA4::encoding_of: Bad input length");
+      throw Encoding_Error("EMSA4::encoding_of: Bad input length");
    if(output_bits < 8*HASH_SIZE + 8*SALT_SIZE + 9)
-      throw Invalid_Argument("EMSA4::encoding_of: Output length is too small");
+      throw Encoding_Error("EMSA4::encoding_of: Output length is too small");

    const u32bit output_length = (output_bits + 7) / 8;

============================================================
--- kdf.cpp	875f93344551fe6e76ca4c86660937d2ec190c60
+++ kdf.cpp	961788f9806afb6dfd141703c9c9eb7f99ecf64c
@@ -12,6 +12,60 @@ namespace Botan {
 namespace Botan {

 /*************************************************
+* Derive a key                                   *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+                                   const MemoryRegion<byte>& secret,
+                                   const std::string& salt) const
+   {
+   return derive_key(key_len, secret, secret.size(),
+                     (const byte*)salt.c_str(), salt.length());
+   }
+
+/*************************************************
+* Derive a key                                   *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+                                   const MemoryRegion<byte>& secret,
+                                   const byte salt[], u32bit salt_len) const
+   {
+   return derive_key(key_len, secret.begin(), secret.size(),
+                     salt, salt_len);
+   }
+
+/*************************************************
+* Derive a key                                   *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+                                   const MemoryRegion<byte>& secret,
+                                   const MemoryRegion<byte>& salt) const
+   {
+   return derive_key(key_len, secret.begin(), secret.size(),
+                     salt.begin(), salt.size());
+   }
+
+/*************************************************
+* Derive a key                                   *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+                                   const byte secret[], u32bit secret_len,
+                                   const std::string& salt) const
+   {
+   return derive_key(key_len, secret, secret_len,
+                     (const byte*)salt.c_str(), salt.length());
+   }
+
+/*************************************************
+* Derive a key                                   *
+*************************************************/
+SecureVector<byte> KDF::derive_key(u32bit key_len,
+                                   const byte secret[], u32bit secret_len,
+                                   const byte salt[], u32bit salt_len) const
+   {
+   return derive(key_len, secret, secret_len, salt, salt_len);
+   }
+
+/*************************************************
 * KDF1 Key Derivation Mechanism                  *
 *************************************************/
 SecureVector<byte> KDF1::derive(u32bit,
============================================================
--- keypair.cpp	b989bff406ff022391d3484840d085d4060715de
+++ keypair.cpp	2c64955c5e28515d0029e50937107dd9a91e3b48
@@ -17,6 +17,9 @@ void check_key(PK_Encryptor* encryptor,
 *************************************************/
 void check_key(PK_Encryptor* encryptor, PK_Decryptor* decryptor)
    {
+   if(encryptor->maximum_input_size() == 0)
+      return;
+
    std::auto_ptr<PK_Encryptor> enc(encryptor);
    std::auto_ptr<PK_Decryptor> dec(decryptor);

@@ -43,8 +46,16 @@ void check_key(PK_Signer* signer, PK_Ver
    SecureVector<byte> message(16);
    Global_RNG::randomize(message, message.size());

-   SecureVector<byte> signature = sig->sign_message(message);
+   SecureVector<byte> signature;

+   try {
+      signature = sig->sign_message(message);
+   }
+   catch(Encoding_Error)
+      {
+      return;
+      }
+
    if(!ver->verify_message(message, signature))
       throw Self_Test_Failure("Signature key pair consistency failure");

============================================================
--- pk_util.cpp	63673b6371f30e1bc06a7ff8e06ab6b9d998bf8b
+++ pk_util.cpp	8237a1130cf67101cdc62f6f63c5378a27ff240b
@@ -59,58 +59,4 @@ bool EMSA::verify(const MemoryRegion<byt
       }
    }

-/*************************************************
-* Derive a key                                   *
-*************************************************/
-SecureVector<byte> KDF::derive_key(u32bit key_len,
-                                   const MemoryRegion<byte>& secret,
-                                   const std::string& salt) const
-   {
-   return derive_key(key_len, secret, secret.size(),
-                     (const byte*)salt.c_str(), salt.length());
-   }
-
-/*************************************************
-* Derive a key                                   *
-*************************************************/
-SecureVector<byte> KDF::derive_key(u32bit key_len,
-                                   const MemoryRegion<byte>& secret,
-                                   const byte salt[], u32bit salt_len) const
-   {
-   return derive_key(key_len, secret.begin(), secret.size(),
-                     salt, salt_len);
-   }
-
-/*************************************************
-* Derive a key                                   *
-*************************************************/
-SecureVector<byte> KDF::derive_key(u32bit key_len,
-                                   const MemoryRegion<byte>& secret,
-                                   const MemoryRegion<byte>& salt) const
-   {
-   return derive_key(key_len, secret.begin(), secret.size(),
-                     salt.begin(), salt.size());
-   }
-
-/*************************************************
-* Derive a key                                   *
-*************************************************/
-SecureVector<byte> KDF::derive_key(u32bit key_len,
-                                   const byte secret[], u32bit secret_len,
-                                   const std::string& salt) const
-   {
-   return derive_key(key_len, secret, secret_len,
-                     (const byte*)salt.c_str(), salt.length());
-   }
-
-/*************************************************
-* Derive a key                                   *
-*************************************************/
-SecureVector<byte> KDF::derive_key(u32bit key_len,
-                                   const byte secret[], u32bit secret_len,
-                                   const byte salt[], u32bit salt_len) const
-   {
-   return derive(key_len, secret, secret_len, salt, salt_len);
-   }
-
 }