1 //====- SHA256.cpp - SHA256 implementation ---*- C++ -* ======// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /* 9 * The SHA-256 Secure Hash Standard was published by NIST in 2002. 10 * 11 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf 12 * 13 * The implementation is based on nacl's sha256 implementation [0] and LLVM's 14 * pre-exsiting SHA1 code [1]. 15 * 16 * [0] https://hyperelliptic.org/nacl/nacl-20110221.tar.bz2 (public domain 17 * code) 18 * [1] llvm/lib/Support/SHA1.{h,cpp} 19 */ 20 //===----------------------------------------------------------------------===// 21 22 #ifndef LLVM_SUPPORT_SHA256_H 23 #define LLVM_SUPPORT_SHA256_H 24 25 #include <array> 26 #include <cstdint> 27 28 namespace llvm { 29 30 template <typename T> class ArrayRef; 31 class StringRef; 32 33 class SHA256 { 34 public: 35 explicit SHA256() { init(); } 36 37 /// Reinitialize the internal state 38 void init(); 39 40 /// Digest more data. 41 void update(ArrayRef<uint8_t> Data); 42 43 /// Digest more data. 44 void update(StringRef Str); 45 46 /// Return the current raw 256-bits SHA256 for the digested 47 /// data since the last call to init(). This call will add data to the 48 /// internal state and as such is not suited for getting an intermediate 49 /// result (see result()). 50 std::array<uint8_t, 32> final(); 51 52 /// Return the current raw 256-bits SHA256 for the digested 53 /// data since the last call to init(). This is suitable for getting the 54 /// SHA256 at any time without invalidating the internal state so that more 55 /// calls can be made into update. 56 std::array<uint8_t, 32> result(); 57 58 /// Returns a raw 256-bit SHA256 hash for the given data. 59 static std::array<uint8_t, 32> hash(ArrayRef<uint8_t> Data); 60 61 private: 62 /// Define some constants. 63 /// "static constexpr" would be cleaner but MSVC does not support it yet. 64 enum { BLOCK_LENGTH = 64 }; 65 enum { HASH_LENGTH = 32 }; 66 67 // Internal State 68 struct { 69 union { 70 uint8_t C[BLOCK_LENGTH]; 71 uint32_t L[BLOCK_LENGTH / 4]; 72 } Buffer; 73 uint32_t State[HASH_LENGTH / 4]; 74 uint32_t ByteCount; 75 uint8_t BufferOffset; 76 } InternalState; 77 78 // Helper 79 void writebyte(uint8_t data); 80 void hashBlock(); 81 void addUncounted(uint8_t data); 82 void pad(); 83 84 void final(std::array<uint32_t, HASH_LENGTH / 4> &HashResult); 85 }; 86 87 } // namespace llvm 88 89 #endif // LLVM_SUPPORT_SHA256_H 90