Botan
1.11.15
|
00001 /* 00002 * DLIES 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/dlies.h> 00009 #include <botan/internal/xor_buf.h> 00010 00011 namespace Botan { 00012 00013 /* 00014 * DLIES_Encryptor Constructor 00015 */ 00016 DLIES_Encryptor::DLIES_Encryptor(const PK_Key_Agreement_Key& key, 00017 KDF* kdf_obj, 00018 MessageAuthenticationCode* mac_obj, 00019 size_t mac_kl) : 00020 ka(key, "Raw"), 00021 kdf(kdf_obj), 00022 mac(mac_obj), 00023 mac_keylen(mac_kl) 00024 { 00025 my_key = key.public_value(); 00026 } 00027 00028 /* 00029 * DLIES Encryption 00030 */ 00031 std::vector<byte> DLIES_Encryptor::enc(const byte in[], size_t length, 00032 RandomNumberGenerator&) const 00033 { 00034 if(length > maximum_input_size()) 00035 throw Invalid_Argument("DLIES: Plaintext too large"); 00036 if(other_key.empty()) 00037 throw Invalid_State("DLIES: The other key was never set"); 00038 00039 secure_vector<byte> out(my_key.size() + length + mac->output_length()); 00040 buffer_insert(out, 0, my_key); 00041 buffer_insert(out, my_key.size(), in, length); 00042 00043 secure_vector<byte> vz(my_key.begin(), my_key.end()); 00044 vz += ka.derive_key(0, other_key).bits_of(); 00045 00046 const size_t K_LENGTH = length + mac_keylen; 00047 secure_vector<byte> K = kdf->derive_key(K_LENGTH, vz); 00048 00049 if(K.size() != K_LENGTH) 00050 throw Encoding_Error("DLIES: KDF did not provide sufficient output"); 00051 byte* C = &out[my_key.size()]; 00052 00053 mac->set_key(&K[0], mac_keylen); 00054 xor_buf(C, &K[mac_keylen], length); 00055 00056 mac->update(C, length); 00057 for(size_t j = 0; j != 8; ++j) 00058 mac->update(0); 00059 00060 mac->final(C + length); 00061 00062 return unlock(out); 00063 } 00064 00065 /* 00066 * Set the other parties public key 00067 */ 00068 void DLIES_Encryptor::set_other_key(const std::vector<byte>& ok) 00069 { 00070 other_key = ok; 00071 } 00072 00073 /* 00074 * Return the max size, in bytes, of a message 00075 */ 00076 size_t DLIES_Encryptor::maximum_input_size() const 00077 { 00078 return 32; 00079 } 00080 00081 /* 00082 * DLIES_Decryptor Constructor 00083 */ 00084 DLIES_Decryptor::DLIES_Decryptor(const PK_Key_Agreement_Key& key, 00085 KDF* kdf_obj, 00086 MessageAuthenticationCode* mac_obj, 00087 size_t mac_kl) : 00088 ka(key, "Raw"), 00089 kdf(kdf_obj), 00090 mac(mac_obj), 00091 mac_keylen(mac_kl) 00092 { 00093 my_key = key.public_value(); 00094 } 00095 00096 /* 00097 * DLIES Decryption 00098 */ 00099 secure_vector<byte> DLIES_Decryptor::dec(const byte msg[], size_t length) const 00100 { 00101 if(length < my_key.size() + mac->output_length()) 00102 throw Decoding_Error("DLIES decryption: ciphertext is too short"); 00103 00104 const size_t CIPHER_LEN = length - my_key.size() - mac->output_length(); 00105 00106 std::vector<byte> v(msg, msg + my_key.size()); 00107 00108 secure_vector<byte> C(msg + my_key.size(), msg + my_key.size() + CIPHER_LEN); 00109 00110 secure_vector<byte> T(msg + my_key.size() + CIPHER_LEN, 00111 msg + my_key.size() + CIPHER_LEN + mac->output_length()); 00112 00113 secure_vector<byte> vz(msg, msg + my_key.size()); 00114 vz += ka.derive_key(0, v).bits_of(); 00115 00116 const size_t K_LENGTH = C.size() + mac_keylen; 00117 secure_vector<byte> K = kdf->derive_key(K_LENGTH, vz); 00118 if(K.size() != K_LENGTH) 00119 throw Encoding_Error("DLIES: KDF did not provide sufficient output"); 00120 00121 mac->set_key(&K[0], mac_keylen); 00122 mac->update(C); 00123 for(size_t j = 0; j != 8; ++j) 00124 mac->update(0); 00125 secure_vector<byte> T2 = mac->final(); 00126 if(T != T2) 00127 throw Decoding_Error("DLIES: message authentication failed"); 00128 00129 xor_buf(C, &K[0] + mac_keylen, C.size()); 00130 00131 return C; 00132 } 00133 00134 }