/************************************************* * Default Engine Algorithms Source File * * (C) 1999-2007 Jack Lloyd * *************************************************/ #include #include #include #if defined(BOTAN_HAS_AES) #include #endif #if defined(BOTAN_HAS_BLOWFISH) #include #endif #if defined(BOTAN_HAS_CAST) #include #include #endif #if defined(BOTAN_HAS_DES) #include #endif #if defined(BOTAN_HAS_GOST) #include #endif #if defined(BOTAN_HAS_IDEA) #include #endif #if defined(BOTAN_HAS_KASUMI) #include #endif #if defined(BOTAN_HAS_LION) #include #endif #if defined(BOTAN_HAS_LUBY_RACKOFF) #include #endif #if defined(BOTAN_HAS_MARS) #include #endif #if defined(BOTAN_HAS_MISTY1) #include #endif #if defined(BOTAN_HAS_NOEKEON) #include #endif #if defined(BOTAN_HAS_RC2) #include #endif #if defined(BOTAN_HAS_RC5) #include #endif #if defined(BOTAN_HAS_RC6) #include #endif #if defined(BOTAN_HAS_SAFER) #include #endif #if defined(BOTAN_HAS_SEED) #include #endif #if defined(BOTAN_HAS_SERPENT) #include #endif #if defined(BOTAN_HAS_SERPENT_IA32) #include #endif #if defined(BOTAN_HAS_SKIPJACK) #include #endif #if defined(BOTAN_HAS_SQUARE) #include #endif #if defined(BOTAN_HAS_TEA) #include #endif #if defined(BOTAN_HAS_TWOFISH) #include #endif #if defined(BOTAN_HAS_XTEA) #include #endif #if defined(BOTAN_HAS_ARC4) #include #endif #if defined(BOTAN_HAS_SALSA20) #include #endif #if defined(BOTAN_HAS_TURING) #include #endif #if defined(BOTAN_HAS_WID_WAKE) #include #endif #if defined(BOTAN_HAS_CIPHER_MODE_PADDING) #include #endif #if defined(BOTAN_HAS_ADLER32) #include #endif #if defined(BOTAN_HAS_CRC24) #include #endif #if defined(BOTAN_HAS_CRC32) #include #endif #if defined(BOTAN_HAS_FORK_256) #include #endif #if defined(BOTAN_HAS_HAS_160) #include #endif #if defined(BOTAN_HAS_MD2) #include #endif #if defined(BOTAN_HAS_MD4) #include #endif #if defined(BOTAN_HAS_MD4_IA32) #include #endif #if defined(BOTAN_HAS_MD5) #include #endif #if defined(BOTAN_HAS_MD5_IA32) #include #endif #if defined(BOTAN_HAS_RIPEMD_128) #include #endif #if defined(BOTAN_HAS_RIPEMD_160) #include #endif #if defined(BOTAN_HAS_SHA1) #include #endif #if defined(BOTAN_HAS_SHA1_IA32) #include #endif #if defined(BOTAN_HAS_SHA1_SSE2) #include #endif #if defined(BOTAN_HAS_SHA1_AMD64) #include #endif #if defined(BOTAN_HAS_SHA2) #include #include #endif #if defined(BOTAN_HAS_TIGER) #include #endif #if defined(BOTAN_HAS_WHIRLPOOL) #include #endif #if defined(BOTAN_HAS_PARALLEL_HASH) #include #endif #if defined(BOTAN_HAS_CBC_MAC) #include #endif #if defined(BOTAN_HAS_CMAC) #include #endif #if defined(BOTAN_HAS_HMAC) #include #endif #if defined(BOTAN_HAS_SSL3_MAC) #include #endif #if defined(BOTAN_HAS_ANSI_X919_MAC) #include #endif #if defined(BOTAN_HAS_PBKDF1) #include #endif #if defined(BOTAN_HAS_PBKDF2) #include #endif #if defined(BOTAN_HAS_PGPS2K) #include #endif namespace Botan { /************************************************* * Some macros to simplify control flow * *************************************************/ #define HANDLE_TYPE_NO_ARGS(NAME, TYPE) \ if(algo_name == NAME) \ { \ if(name.size() == 1) \ return new TYPE; \ throw Invalid_Algorithm_Name(algo_spec); \ } #define HANDLE_TYPE_ONE_U32BIT(NAME, TYPE, DEFAULT) \ if(algo_name == NAME) \ { \ if(name.size() == 1) \ return new TYPE(DEFAULT); \ if(name.size() == 2) \ return new TYPE(to_u32bit(name[1])); \ throw Invalid_Algorithm_Name(algo_spec); \ } #define HANDLE_TYPE_TWO_U32BIT(NAME, TYPE, DEFAULT) \ if(algo_name == NAME) \ { \ if(name.size() == 1) \ return new TYPE(DEFAULT); \ if(name.size() == 2) \ return new TYPE(to_u32bit(name[1])); \ if(name.size() == 3) \ return new TYPE(to_u32bit(name[1]), to_u32bit(name[2])); \ throw Invalid_Algorithm_Name(algo_spec); \ } #define HANDLE_TYPE_ONE_STRING(NAME, TYPE) \ if(algo_name == NAME) \ { \ if(name.size() == 2) \ return new TYPE(name[1]); \ throw Invalid_Algorithm_Name(algo_spec); \ } /************************************************* * Look for an algorithm with this name * *************************************************/ BlockCipher* Default_Engine::find_block_cipher(const std::string& algo_spec) const { std::vector name = parse_algorithm_name(algo_spec); if(name.empty()) return 0; const std::string algo_name = global_state().deref_alias(name[0]); #if defined(BOTAN_HAS_AES) HANDLE_TYPE_NO_ARGS("AES", AES); HANDLE_TYPE_NO_ARGS("AES-128", AES_128); HANDLE_TYPE_NO_ARGS("AES-192", AES_192); HANDLE_TYPE_NO_ARGS("AES-256", AES_256); #endif #if defined(BOTAN_HAS_BLOWFISH) HANDLE_TYPE_NO_ARGS("Blowfish", Blowfish); #endif #if defined(BOTAN_HAS_CAST) HANDLE_TYPE_NO_ARGS("CAST-128", CAST_128); HANDLE_TYPE_NO_ARGS("CAST-256", CAST_256); #endif #if defined(BOTAN_HAS_DES) HANDLE_TYPE_NO_ARGS("DES", DES); HANDLE_TYPE_NO_ARGS("DESX", DESX); HANDLE_TYPE_NO_ARGS("TripleDES", TripleDES); #endif #if defined(BOTAN_HAS_GOST) HANDLE_TYPE_NO_ARGS("GOST", GOST); #endif #if defined(BOTAN_HAS_IDEA) HANDLE_TYPE_NO_ARGS("IDEA", IDEA); #endif #if defined(BOTAN_HAS_KASUMI) HANDLE_TYPE_NO_ARGS("KASUMI", KASUMI); #endif #if defined(BOTAN_HAS_MARS) HANDLE_TYPE_NO_ARGS("MARS", MARS); #endif #if defined(BOTAN_HAS_MISTY1) HANDLE_TYPE_ONE_U32BIT("MISTY1", MISTY1, 8); #endif #if defined(BOTAN_HAS_NOEKEON) HANDLE_TYPE_NO_ARGS("Noekeon", Noekeon); #endif #if defined(BOTAN_HAS_RC2) HANDLE_TYPE_NO_ARGS("RC2", RC2); #endif #if defined(BOTAN_HAS_RC5) HANDLE_TYPE_ONE_U32BIT("RC5", RC5, 12); #endif #if defined(BOTAN_HAS_RC6) HANDLE_TYPE_NO_ARGS("RC6", RC6); #endif #if defined(BOTAN_HAS_SAFER) HANDLE_TYPE_ONE_U32BIT("SAFER-SK", SAFER_SK, 10); #endif #if defined(BOTAN_HAS_SEED) HANDLE_TYPE_NO_ARGS("SEED", SEED); #endif #if defined(BOTAN_HAS_SERPENT_IA32) HANDLE_TYPE_NO_ARGS("Serpent", Serpent_IA32); #elif defined(BOTAN_HAS_SERPENT) HANDLE_TYPE_NO_ARGS("Serpent", Serpent); #endif #if defined(BOTAN_HAS_SKIPJACK) HANDLE_TYPE_NO_ARGS("Skipjack", Skipjack); #endif #if defined(BOTAN_HAS_SQUARE) HANDLE_TYPE_NO_ARGS("Square", Square); #endif #if defined(BOTAN_HAS_TEA) HANDLE_TYPE_NO_ARGS("TEA", TEA); #endif #if defined(BOTAN_HAS_TWOFISH) HANDLE_TYPE_NO_ARGS("Twofish", Twofish); #endif #if defined(BOTAN_HAS_XTEA) HANDLE_TYPE_NO_ARGS("XTEA", XTEA); #endif #if defined(BOTAN_HAS_LUBY_RACKOFF) if(algo_name == "Luby-Rackoff" && name.size() >= 2) { HashFunction* hash = find_hash(name[1]); if(hash) return new LubyRackoff(hash); } #endif #if defined(BOTAN_HAS_LION) if(algo_name == "Lion") { if(name.size() != 4) throw Invalid_Algorithm_Name(algo_spec); return new Lion(name[1], name[2], to_u32bit(name[3])); } #endif return 0; } /************************************************* * Look for an algorithm with this name * *************************************************/ StreamCipher* Default_Engine::find_stream_cipher(const std::string& algo_spec) const { std::vector name = parse_algorithm_name(algo_spec); if(name.empty()) return 0; const std::string algo_name = global_state().deref_alias(name[0]); #if defined(BOTAN_HAS_ARC4) HANDLE_TYPE_ONE_U32BIT("ARC4", ARC4, 0); HANDLE_TYPE_ONE_U32BIT("RC4_drop", ARC4, 768); #endif #if defined(BOTAN_HAS_SALSA20) HANDLE_TYPE_NO_ARGS("Salsa20", Salsa20); #endif #if defined(BOTAN_HAS_TURING) HANDLE_TYPE_NO_ARGS("Turing", Turing); #endif #if defined(BOTAN_HAS_WID_WAKE) HANDLE_TYPE_NO_ARGS("WiderWake4+1-BE", WiderWake_41_BE); #endif return 0; } /************************************************* * Look for an algorithm with this name * *************************************************/ HashFunction* Default_Engine::find_hash(const std::string& algo_spec) const { std::vector name = parse_algorithm_name(algo_spec); if(name.empty()) return 0; const std::string algo_name = global_state().deref_alias(name[0]); #if defined(BOTAN_HAS_ADLER32) HANDLE_TYPE_NO_ARGS("Adler32", Adler32); #endif #if defined(BOTAN_HAS_CRC24) HANDLE_TYPE_NO_ARGS("CRC24", CRC24); #endif #if defined(BOTAN_HAS_CRC32) HANDLE_TYPE_NO_ARGS("CRC32", CRC32); #endif #if defined(BOTAN_HAS_FORK_256) HANDLE_TYPE_NO_ARGS("FORK-256", FORK_256); #endif #if defined(BOTAN_HAS_HAS_160) HANDLE_TYPE_NO_ARGS("HAS-160", HAS_160); #endif #if defined(BOTAN_HAS_MD2) HANDLE_TYPE_NO_ARGS("MD2", MD2); #endif #if defined(BOTAN_HAS_MD4_IA32) HANDLE_TYPE_NO_ARGS("MD4", MD4_IA32); #elif defined(BOTAN_HAS_MD4) HANDLE_TYPE_NO_ARGS("MD4", MD4); #endif #if defined(BOTAN_HAS_MD5_IA32) HANDLE_TYPE_NO_ARGS("MD5", MD5_IA32); #elif defined(BOTAN_HAS_MD5) HANDLE_TYPE_NO_ARGS("MD5", MD5); #endif #if defined(BOTAN_HAS_RIPEMD_128) HANDLE_TYPE_NO_ARGS("RIPEMD-128", RIPEMD_128); #endif #if defined(BOTAN_HAS_RIPEMD_160) HANDLE_TYPE_NO_ARGS("RIPEMD-160", RIPEMD_160); #endif #if defined(BOTAN_HAS_SHA1_SSE2) HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160_SSE2); #elif defined(BOTAN_HAS_SHA1_AMD64) HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160_AMD64); #elif defined(BOTAN_HAS_SHA1_IA32) HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160_IA32); #elif defined(BOTAN_HAS_SHA1) HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160); #endif #if defined(BOTAN_HAS_SHA2) HANDLE_TYPE_NO_ARGS("SHA-256", SHA_256); HANDLE_TYPE_NO_ARGS("SHA-384", SHA_384); HANDLE_TYPE_NO_ARGS("SHA-512", SHA_512); #endif #if defined(BOTAN_HAS_TIGER) HANDLE_TYPE_TWO_U32BIT("Tiger", Tiger, 24); #endif #if defined(BOTAN_HAS_WHIRLPOOL) HANDLE_TYPE_NO_ARGS("Whirlpool", Whirlpool); #endif if(algo_name == "Parallel") { if(name.size() < 2) throw Invalid_Algorithm_Name(algo_spec); name.erase(name.begin()); return new Parallel(name); } return 0; } /************************************************* * Look for an algorithm with this name * *************************************************/ MessageAuthenticationCode* Default_Engine::find_mac(const std::string& algo_spec) const { std::vector name = parse_algorithm_name(algo_spec); if(name.empty()) return 0; const std::string algo_name = global_state().deref_alias(name[0]); #if defined(BOTAN_HAS_CBC_MAC) HANDLE_TYPE_ONE_STRING("CBC-MAC", CBC_MAC); #endif #if defined(BOTAN_HAS_CMAC) HANDLE_TYPE_ONE_STRING("CMAC", CMAC); #endif #if defined(BOTAN_HAS_HMAC) HANDLE_TYPE_ONE_STRING("HMAC", HMAC); #endif #if defined(BOTAN_HAS_SSL3_MAC) HANDLE_TYPE_ONE_STRING("SSL3-MAC", SSL3_MAC); #endif #if defined(BOTAN_HAS_ANSI_X919_MAC) HANDLE_TYPE_NO_ARGS("X9.19-MAC", ANSI_X919_MAC); #endif return 0; } /************************************************* * Look for an algorithm with this name * *************************************************/ S2K* Default_Engine::find_s2k(const std::string& algo_spec) const { std::vector name = parse_algorithm_name(algo_spec); if(name.empty()) return 0; const std::string algo_name = global_state().deref_alias(name[0]); #if defined(BOTAN_HAS_PBKDF1) HANDLE_TYPE_ONE_STRING("PBKDF1", PKCS5_PBKDF1); #endif #if defined(BOTAN_HAS_PBKDF2) HANDLE_TYPE_ONE_STRING("PBKDF2", PKCS5_PBKDF2); #endif #if defined(BOTAN_HAS_PGPS2K) HANDLE_TYPE_ONE_STRING("OpenPGP-S2K", OpenPGP_S2K); #endif return 0; } /************************************************* * Look for an algorithm with this name * *************************************************/ BlockCipherModePaddingMethod* Default_Engine::find_bc_pad(const std::string& algo_spec) const { std::vector name = parse_algorithm_name(algo_spec); if(name.empty()) return 0; const std::string algo_name = global_state().deref_alias(name[0]); #if defined(BOTAN_HAS_CIPHER_MODE_PADDING) HANDLE_TYPE_NO_ARGS("PKCS7", PKCS7_Padding); HANDLE_TYPE_NO_ARGS("OneAndZeros", OneAndZeros_Padding); HANDLE_TYPE_NO_ARGS("X9.23", ANSI_X923_Padding); HANDLE_TYPE_NO_ARGS("NoPadding", Null_Padding); #endif return 0; } }