1 #ifndef PICHI_CRYPTO_HASH_HPP 2 #define PICHI_CRYPTO_HASH_HPP 3 4 #include <mbedtls/md5.h> 5 #include <mbedtls/sha1.h> 6 #include <mbedtls/sha256.h> 7 #include <mbedtls/sha512.h> 8 #include <pichi/common/buffer.hpp> 9 #include <pichi/common/enumerations.hpp> 10 11 #if MBEDTLS_VERSION_MAJOR >= 3 12 #define mbedtls_md5_starts_ret mbedtls_md5_starts 13 #define mbedtls_sha1_starts_ret mbedtls_sha1_starts 14 #define mbedtls_sha256_starts_ret mbedtls_sha256_starts 15 #define mbedtls_sha512_starts_ret mbedtls_sha512_starts 16 #define mbedtls_md5_update_ret mbedtls_md5_update 17 #define mbedtls_sha1_update_ret mbedtls_sha1_update 18 #define mbedtls_sha256_update_ret mbedtls_sha256_update 19 #define mbedtls_sha512_update_ret mbedtls_sha512_update 20 #define mbedtls_md5_finish_ret mbedtls_md5_finish 21 #define mbedtls_sha1_finish_ret mbedtls_sha1_finish 22 #define mbedtls_sha256_finish_ret mbedtls_sha256_finish 23 #define mbedtls_sha512_finish_ret mbedtls_sha512_finish 24 #endif // MBEDTLS_VERSION_MAJOR >= 3 25 26 namespace pichi::crypto { 27 28 // TODO use lambda if compiler supports 29 struct StartFunctions { sha224pichi::crypto::StartFunctions30 inline static int sha224(mbedtls_sha256_context* ctx) 31 { 32 return mbedtls_sha256_starts_ret(ctx, 1); 33 } sha256pichi::crypto::StartFunctions34 inline static int sha256(mbedtls_sha256_context* ctx) 35 { 36 return mbedtls_sha256_starts_ret(ctx, 0); 37 } sha384pichi::crypto::StartFunctions38 inline static int sha384(mbedtls_sha512_context* ctx) 39 { 40 return mbedtls_sha512_starts_ret(ctx, 1); 41 } sha512pichi::crypto::StartFunctions42 inline static int sha512(mbedtls_sha512_context* ctx) 43 { 44 return mbedtls_sha512_starts_ret(ctx, 0); 45 } 46 }; 47 48 template <HashAlgorithm algorithm> struct HashTraits { 49 }; 50 51 template <> struct HashTraits<HashAlgorithm::MD5> { 52 using Context = mbedtls_md5_context; 53 static constexpr auto initialize = mbedtls_md5_init; 54 static constexpr auto start = mbedtls_md5_starts_ret; 55 static constexpr auto clone = mbedtls_md5_clone; 56 static constexpr auto release = mbedtls_md5_free; 57 static constexpr auto update = mbedtls_md5_update_ret; 58 static constexpr auto finish = mbedtls_md5_finish_ret; 59 static size_t const length = 16; 60 static size_t const block_size = 64; 61 }; 62 63 template <> struct HashTraits<HashAlgorithm::SHA1> { 64 using Context = mbedtls_sha1_context; 65 static constexpr auto initialize = mbedtls_sha1_init; 66 static constexpr auto start = mbedtls_sha1_starts_ret; 67 static constexpr auto clone = mbedtls_sha1_clone; 68 static constexpr auto release = mbedtls_sha1_free; 69 static constexpr auto update = mbedtls_sha1_update_ret; 70 static constexpr auto finish = mbedtls_sha1_finish_ret; 71 static size_t const length = 20; 72 static size_t const block_size = 64; 73 }; 74 75 template <> struct HashTraits<HashAlgorithm::SHA224> { 76 using Context = mbedtls_sha256_context; 77 static constexpr auto initialize = mbedtls_sha256_init; 78 static constexpr auto start = StartFunctions::sha224; 79 static constexpr auto clone = mbedtls_sha256_clone; 80 static constexpr auto release = mbedtls_sha256_free; 81 static constexpr auto update = mbedtls_sha256_update_ret; 82 static constexpr auto finish = mbedtls_sha256_finish_ret; 83 static size_t const length = 28; 84 static size_t const block_size = 64; 85 }; 86 87 template <> struct HashTraits<HashAlgorithm::SHA256> { 88 using Context = mbedtls_sha256_context; 89 static constexpr auto initialize = mbedtls_sha256_init; 90 static constexpr auto start = StartFunctions::sha256; 91 static constexpr auto clone = mbedtls_sha256_clone; 92 static constexpr auto release = mbedtls_sha256_free; 93 static constexpr auto update = mbedtls_sha256_update_ret; 94 static constexpr auto finish = mbedtls_sha256_finish_ret; 95 static size_t const length = 32; 96 static size_t const block_size = 64; 97 }; 98 99 template <> struct HashTraits<HashAlgorithm::SHA384> { 100 using Context = mbedtls_sha512_context; 101 static constexpr auto initialize = mbedtls_sha512_init; 102 static constexpr auto start = StartFunctions::sha384; 103 static constexpr auto clone = mbedtls_sha512_clone; 104 static constexpr auto release = mbedtls_sha512_free; 105 static constexpr auto update = mbedtls_sha512_update_ret; 106 static constexpr auto finish = mbedtls_sha512_finish_ret; 107 static size_t const length = 48; 108 static size_t const block_size = 128; 109 }; 110 111 template <> struct HashTraits<HashAlgorithm::SHA512> { 112 using Context = mbedtls_sha512_context; 113 static constexpr auto initialize = mbedtls_sha512_init; 114 static constexpr auto start = StartFunctions::sha512; 115 static constexpr auto clone = mbedtls_sha512_clone; 116 static constexpr auto release = mbedtls_sha512_free; 117 static constexpr auto update = mbedtls_sha512_update_ret; 118 static constexpr auto finish = mbedtls_sha512_finish_ret; 119 static size_t const length = 64; 120 static size_t const block_size = 128; 121 }; 122 123 template <HashAlgorithm algorithm> class Hash { 124 private: 125 using Traits = HashTraits<algorithm>; 126 using Context = typename Traits::Context; 127 128 public: 129 Hash& operator=(Hash const&) = delete; 130 Hash& operator=(Hash&&) = delete; 131 132 Hash(Hash const&); 133 Hash(Hash&&); 134 135 public: 136 Hash(); 137 ~Hash(); 138 139 void append(ConstBuffer<uint8_t>); 140 size_t hash(MutableBuffer<uint8_t>); 141 size_t hash(ConstBuffer<uint8_t>, MutableBuffer<uint8_t>); 142 143 private: 144 Context ctx_; 145 }; 146 147 template <HashAlgorithm algorithm> class Hmac { 148 private: 149 using H = Hash<algorithm>; 150 using Traits = HashTraits<algorithm>; 151 152 public: 153 Hmac& operator=(Hmac const&) = delete; 154 Hmac& operator=(Hmac&&) = delete; 155 156 Hmac(Hmac const&) = default; 157 Hmac(Hmac&&) = default; 158 159 public: 160 Hmac(ConstBuffer<uint8_t> key); 161 void append(ConstBuffer<uint8_t>); 162 size_t hash(MutableBuffer<uint8_t>); 163 size_t hash(ConstBuffer<uint8_t>, MutableBuffer<uint8_t>); 164 165 private: 166 H i_; 167 H o_; 168 }; 169 170 template <HashAlgorithm algorithm> 171 void hkdf(MutableBuffer<uint8_t> okm, ConstBuffer<uint8_t> ikm, ConstBuffer<uint8_t> salt, 172 ConstBuffer<uint8_t> info = {(uint8_t const*)"ss-subkey", 9}); 173 174 std::string bin2hex(ConstBuffer<uint8_t> bin); 175 176 } // namespace pichi::crypto 177 178 #endif // PICHI_CRYPTO_HASH_HPP 179