Botan  1.11.15
src/lib/pubkey/dlies/dlies.cpp
Go to the documentation of this file.
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 }