1 /*
2 * Adding an application specific engine
3 * (C) 2004,2008 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/stream_cipher.h>
9 #include <botan/engine.h>
10
11 using namespace Botan;
12
13 class XOR_Cipher : public StreamCipher
14 {
15 public:
clear()16 void clear() throw() { mask.clear(); mask_pos = 0; }
17
18 // what we want to call this cipher
name() const19 std::string name() const { return "XOR"; }
20
21 // return a new object of this type
clone() const22 StreamCipher* clone() const { return new XOR_Cipher; }
23
key_spec() const24 Key_Length_Specification key_spec() const
25 {
26 return Key_Length_Specification(1, 32);
27 }
28
XOR_Cipher()29 XOR_Cipher() : mask_pos(0) {}
30 private:
cipher(const byte in[],byte out[],size_t length)31 void cipher(const byte in[], byte out[], size_t length)
32 {
33 for(size_t j = 0; j != length; j++)
34 {
35 out[j] = in[j] ^ mask[mask_pos];
36 mask_pos = (mask_pos + 1) % mask.size();
37 }
38 }
39
key_schedule(const byte key[],size_t length)40 void key_schedule(const byte key[], size_t length)
41 {
42 mask.resize(length);
43 copy_mem(&mask[0], key, length);
44 }
45
46 SecureVector<byte> mask;
47 u32bit mask_pos;
48 };
49
50 class Application_Engine : public Engine
51 {
52 public:
provider_name() const53 std::string provider_name() const { return "application"; }
54
find_stream_cipher(const SCAN_Name & request,Algorithm_Factory &) const55 StreamCipher* find_stream_cipher(const SCAN_Name& request,
56 Algorithm_Factory&) const
57 {
58 if(request.algo_name() == "XOR")
59 return new XOR_Cipher;
60 return 0;
61 }
62 };
63
64 #include <botan/botan.h>
65 #include <iostream>
66 #include <string>
67
main()68 int main()
69 {
70
71 Botan::LibraryInitializer init;
72
73 global_state().algorithm_factory().add_engine(
74 new Application_Engine);
75
76 // a hex key value
77 SymmetricKey key("010203040506070809101112AAFF");
78
79 /*
80 Since stream ciphers are typically additive, the encryption and
81 decryption ops are the same, so this isn't terribly interesting.
82
83 If this where a block cipher you would have to add a cipher mode and
84 padding method, such as "/CBC/PKCS7".
85 */
86 Pipe enc(get_cipher("XOR", key, ENCRYPTION), new Hex_Encoder);
87 Pipe dec(new Hex_Decoder, get_cipher("XOR", key, DECRYPTION));
88
89 // I think the pigeons are actually asleep at midnight...
90 std::string secret = "The pigeon flys at midnight.";
91
92 std::cout << "The secret message is '" << secret << "'" << std::endl;
93
94 enc.process_msg(secret);
95 std::string cipher = enc.read_all_as_string();
96
97 std::cout << "The encrypted secret message is " << cipher << std::endl;
98
99 dec.process_msg(cipher);
100 secret = dec.read_all_as_string();
101
102 std::cout << "The decrypted secret message is '"
103 << secret << "'" << std::endl;
104
105 return 0;
106 }
107