Botan  1.11.15
src/lib/modes/aead/gcm/gcm.h
Go to the documentation of this file.
00001 /*
00002 * GCM Mode
00003 * (C) 2013 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #ifndef BOTAN_AEAD_GCM_H__
00009 #define BOTAN_AEAD_GCM_H__
00010 
00011 #include <botan/aead.h>
00012 #include <botan/block_cipher.h>
00013 #include <botan/stream_cipher.h>
00014 
00015 namespace Botan {
00016 
00017 class GHASH;
00018 
00019 /**
00020 * GCM Mode
00021 */
00022 class BOTAN_DLL GCM_Mode : public AEAD_Mode
00023    {
00024    public:
00025       void set_associated_data(const byte ad[], size_t ad_len) override;
00026 
00027       std::string name() const override;
00028 
00029       size_t update_granularity() const;
00030 
00031       Key_Length_Specification key_spec() const override;
00032 
00033       // GCM supports arbitrary nonce lengths
00034       bool valid_nonce_length(size_t) const override { return true; }
00035 
00036       size_t tag_size() const override { return m_tag_size; }
00037 
00038       void clear() override;
00039    protected:
00040       GCM_Mode(BlockCipher* cipher, size_t tag_size);
00041 
00042       const size_t BS = 16;
00043 
00044       const size_t m_tag_size;
00045       const std::string m_cipher_name;
00046 
00047       std::unique_ptr<StreamCipher> m_ctr;
00048       std::unique_ptr<GHASH> m_ghash;
00049    private:
00050       secure_vector<byte> start_raw(const byte nonce[], size_t nonce_len) override;
00051 
00052       void key_schedule(const byte key[], size_t length) override;
00053    };
00054 
00055 /**
00056 * GCM Encryption
00057 */
00058 class BOTAN_DLL GCM_Encryption : public GCM_Mode
00059    {
00060    public:
00061       /**
00062       * @param cipher the 128 bit block cipher to use
00063       * @param tag_size is how big the auth tag will be
00064       */
00065       GCM_Encryption(BlockCipher* cipher, size_t tag_size = 16) :
00066          GCM_Mode(cipher, tag_size) {}
00067 
00068       size_t output_length(size_t input_length) const override
00069          { return input_length + tag_size(); }
00070 
00071       size_t minimum_final_size() const override { return 0; }
00072 
00073       void update(secure_vector<byte>& blocks, size_t offset = 0) override;
00074 
00075       void finish(secure_vector<byte>& final_block, size_t offset = 0) override;
00076    };
00077 
00078 /**
00079 * GCM Decryption
00080 */
00081 class BOTAN_DLL GCM_Decryption : public GCM_Mode
00082    {
00083    public:
00084       /**
00085       * @param cipher the 128 bit block cipher to use
00086       * @param tag_size is how big the auth tag will be
00087       */
00088       GCM_Decryption(BlockCipher* cipher, size_t tag_size = 16) :
00089          GCM_Mode(cipher, tag_size) {}
00090 
00091       size_t output_length(size_t input_length) const override
00092          {
00093          BOTAN_ASSERT(input_length > tag_size(), "Sufficient input");
00094          return input_length - tag_size();
00095          }
00096 
00097       size_t minimum_final_size() const override { return tag_size(); }
00098 
00099       void update(secure_vector<byte>& blocks, size_t offset = 0) override;
00100 
00101       void finish(secure_vector<byte>& final_block, size_t offset = 0) override;
00102    };
00103 
00104 /**
00105 * GCM's GHASH
00106 * Maybe a Transform?
00107 */
00108 class BOTAN_DLL GHASH : public SymmetricAlgorithm
00109    {
00110    public:
00111       void set_associated_data(const byte ad[], size_t ad_len);
00112 
00113       secure_vector<byte> nonce_hash(const byte nonce[], size_t len);
00114 
00115       void start(const byte nonce[], size_t len);
00116 
00117       /*
00118       * Assumes input len is multiple of 16
00119       */
00120       void update(const byte in[], size_t len);
00121 
00122       secure_vector<byte> final();
00123 
00124       Key_Length_Specification key_spec() const { return Key_Length_Specification(16); }
00125 
00126       void clear() override;
00127 
00128       std::string name() const { return "GHASH"; }
00129    private:
00130       void key_schedule(const byte key[], size_t key_len) override;
00131 
00132       void gcm_multiply(secure_vector<byte>& x) const;
00133 
00134       void ghash_update(secure_vector<byte>& x,
00135                         const byte input[], size_t input_len);
00136 
00137       void add_final_block(secure_vector<byte>& x,
00138                            size_t ad_len, size_t pt_len);
00139 
00140       secure_vector<byte> m_H;
00141       secure_vector<byte> m_H_ad;
00142       secure_vector<byte> m_nonce;
00143       secure_vector<byte> m_ghash;
00144       size_t m_ad_len = 0, m_text_len = 0;
00145    };
00146 
00147 }
00148 
00149 #endif