Botan  1.11.15
src/lib/pubkey/mceies/mceies.cpp
Go to the documentation of this file.
00001 /*
00002 * McEliece Integrated Encryption System
00003 * (C) 2014,2015 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/mceies.h>
00009 #include <botan/aead.h>
00010 #include <botan/mceliece.h>
00011 #include <botan/mce_kem.h>
00012 
00013 namespace Botan {
00014 
00015 namespace {
00016 
00017 secure_vector<byte> aead_key(const secure_vector<byte>& mk,
00018                              const AEAD_Mode& aead)
00019    {
00020    // Fold the key as required for the AEAD mode in use
00021    if(aead.valid_keylength(mk.size()))
00022       return mk;
00023 
00024    secure_vector<byte> r(aead.key_spec().maximum_keylength());
00025    for(size_t i = 0; i != mk.size(); ++i)
00026       r[i % r.size()] ^= mk[i];
00027    return r;
00028    }
00029 
00030 }
00031 
00032 secure_vector<byte>
00033 mceies_encrypt(const McEliece_PublicKey& pubkey,
00034                const secure_vector<byte>& pt,
00035                byte ad[], size_t ad_len,
00036                RandomNumberGenerator& rng)
00037    {
00038    McEliece_KEM_Encryptor kem_op(pubkey);
00039 
00040    const std::pair<secure_vector<byte>,secure_vector<byte>> mce_ciphertext__key = kem_op.encrypt(rng);
00041    const secure_vector<byte>& mce_ciphertext = mce_ciphertext__key.first;
00042    const secure_vector<byte>& mce_key = mce_ciphertext__key.second;
00043 
00044    const size_t mce_code_bytes = (pubkey.get_code_length() + 7) / 8;
00045 
00046    BOTAN_ASSERT(mce_ciphertext.size() == mce_code_bytes, "Unexpected size");
00047 
00048    std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/OCB", ENCRYPTION));
00049    if(!aead)
00050       throw std::runtime_error("mce_encrypt unable to create AEAD instance");
00051 
00052    const size_t nonce_len = aead->default_nonce_length();
00053 
00054    aead->set_key(aead_key(mce_key, *aead));
00055    aead->set_associated_data(ad, ad_len);
00056 
00057    const secure_vector<byte> nonce = rng.random_vec(nonce_len);
00058 
00059    secure_vector<byte> msg(mce_ciphertext.size() + nonce.size() + pt.size());
00060    copy_mem(&msg[0], &mce_ciphertext[0], mce_ciphertext.size());
00061    copy_mem(&msg[mce_ciphertext.size()], &nonce[0], nonce.size());
00062    copy_mem(&msg[mce_ciphertext.size() + nonce.size()], &pt[0], pt.size());
00063 
00064    aead->start(nonce);
00065    aead->finish(msg, mce_ciphertext.size() + nonce.size());
00066    return msg;
00067    }
00068 
00069 secure_vector<byte>
00070 mceies_decrypt(const McEliece_PrivateKey& privkey,
00071                const secure_vector<byte>& ct,
00072                byte ad[], size_t ad_len)
00073    {
00074    try
00075       {
00076       McEliece_KEM_Decryptor kem_op(privkey);
00077 
00078       const size_t mce_code_bytes = (privkey.get_code_length() + 7) / 8;
00079 
00080       std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/OCB", DECRYPTION));
00081       if(!aead)
00082          throw std::runtime_error("Unable to create AEAD instance");
00083 
00084       const size_t nonce_len = aead->default_nonce_length();
00085 
00086       if(ct.size() < mce_code_bytes + nonce_len + aead->tag_size())
00087          throw std::runtime_error("Input message too small to be valid");
00088 
00089       const secure_vector<byte> mce_key = kem_op.decrypt(&ct[0], mce_code_bytes);
00090 
00091       aead->set_key(aead_key(mce_key, *aead));
00092       aead->set_associated_data(ad, ad_len);
00093 
00094       secure_vector<byte> pt(&ct[mce_code_bytes + nonce_len], &ct[ct.size()]);
00095 
00096       aead->start(&ct[mce_code_bytes], nonce_len);
00097       aead->finish(pt, 0);
00098       return pt;
00099       }
00100    catch(std::exception& e)
00101       {
00102       throw std::runtime_error("mce_decrypt failed: " + std::string(e.what()));
00103       }
00104    }
00105 
00106 }