1 /* 2 * GCM Mode 3 * (C) 2013 Jack Lloyd 4 * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity 5 * 6 * Botan is released under the Simplified BSD License (see license.txt) 7 */ 8 9 #ifndef BOTAN_AEAD_GCM_H_ 10 #define BOTAN_AEAD_GCM_H_ 11 12 #include <botan/aead.h> 13 #include <botan/sym_algo.h> 14 15 BOTAN_FUTURE_INTERNAL_HEADER(gcm.h) 16 17 namespace Botan { 18 19 class BlockCipher; 20 class StreamCipher; 21 class GHASH; 22 23 /** 24 * GCM Mode 25 */ 26 class BOTAN_PUBLIC_API(2,0) GCM_Mode : public AEAD_Mode 27 { 28 public: 29 void set_associated_data(const uint8_t ad[], size_t ad_len) override; 30 31 std::string name() const override; 32 33 size_t update_granularity() const override; 34 35 Key_Length_Specification key_spec() const override; 36 37 bool valid_nonce_length(size_t len) const override; 38 tag_size()39 size_t tag_size() const override { return m_tag_size; } 40 41 void clear() override; 42 43 void reset() override; 44 45 std::string provider() const override; 46 protected: 47 GCM_Mode(BlockCipher* cipher, size_t tag_size); 48 49 ~GCM_Mode(); 50 51 static const size_t GCM_BS = 16; 52 53 const size_t m_tag_size; 54 const std::string m_cipher_name; 55 56 std::unique_ptr<StreamCipher> m_ctr; 57 std::unique_ptr<GHASH> m_ghash; 58 private: 59 void start_msg(const uint8_t nonce[], size_t nonce_len) override; 60 61 void key_schedule(const uint8_t key[], size_t length) override; 62 63 secure_vector<uint8_t> m_y0; 64 }; 65 66 /** 67 * GCM Encryption 68 */ 69 class BOTAN_PUBLIC_API(2,0) GCM_Encryption final : public GCM_Mode 70 { 71 public: 72 /** 73 * @param cipher the 128 bit block cipher to use 74 * @param tag_size is how big the auth tag will be 75 */ 76 GCM_Encryption(BlockCipher* cipher, size_t tag_size = 16) : GCM_Mode(cipher,tag_size)77 GCM_Mode(cipher, tag_size) {} 78 output_length(size_t input_length)79 size_t output_length(size_t input_length) const override 80 { return input_length + tag_size(); } 81 minimum_final_size()82 size_t minimum_final_size() const override { return 0; } 83 84 size_t process(uint8_t buf[], size_t size) override; 85 86 void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override; 87 }; 88 89 /** 90 * GCM Decryption 91 */ 92 class BOTAN_PUBLIC_API(2,0) GCM_Decryption final : public GCM_Mode 93 { 94 public: 95 /** 96 * @param cipher the 128 bit block cipher to use 97 * @param tag_size is how big the auth tag will be 98 */ 99 GCM_Decryption(BlockCipher* cipher, size_t tag_size = 16) : GCM_Mode(cipher,tag_size)100 GCM_Mode(cipher, tag_size) {} 101 output_length(size_t input_length)102 size_t output_length(size_t input_length) const override 103 { 104 BOTAN_ASSERT(input_length >= tag_size(), "Sufficient input"); 105 return input_length - tag_size(); 106 } 107 minimum_final_size()108 size_t minimum_final_size() const override { return tag_size(); } 109 110 size_t process(uint8_t buf[], size_t size) override; 111 112 void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) override; 113 }; 114 115 } 116 117 #endif 118