Botan
1.11.15
|
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 }