3 * Copyright (C) 2023 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_SHA1_UTILS_HPP_INCLUDED
19 #define CARLA_SHA1_UTILS_HPP_INCLUDED
21 #include "CarlaUtils.hpp"
23 #if defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
24 # define CARLA_SHA1_BIG_ENDIAN
28 * Simple, single-use SHA1 class.
29 * Must be discarded after use.
31 * Based on libcrypt by Wei Dai and other contributors (originally in the public domain)
34 static constexpr const size_t BLOCK_LENGTH
= 64;
37 uint8_t u8
[BLOCK_LENGTH
];
38 uint32_t u32
[BLOCK_LENGTH
/sizeof(uint32_t)];
45 static_assert(sizeof(buffer
.u8
) == sizeof(buffer
.u32
), "valid size");
55 state
[0] = 0x67452301;
56 state
[1] = 0xefcdab89;
57 state
[2] = 0x98badcfe;
58 state
[3] = 0x10325476;
59 state
[4] = 0xc3d2e1f0;
63 * Write a single byte of data.
65 void writeByte(const uint8_t data
) noexcept
72 * Write a custom blob of data.
74 void write(const void* const data
, size_t len
) noexcept
76 const uint8_t* u8data
= static_cast<const uint8_t*>(data
);
83 * Return hash result as byte array (20 characters).
84 * @note must be called only once!
86 const uint8_t* resultAsHash() noexcept
88 // Pad to complete the last block
91 #ifndef CARLA_SHA1_BIG_ENDIAN
92 // Swap byte order back
93 for (int i
=0; i
<5; ++i
)
95 state
[i
] = ((state
[i
] << 24) & 0xff000000)
96 | ((state
[i
] << 8) & 0x00ff0000)
97 | ((state
[i
] >> 8) & 0x0000ff00)
98 | ((state
[i
] >> 24) & 0x000000ff);
102 return static_cast<uint8_t*>(static_cast<void*>(state
));
106 * Return hash result as null-terminated string.
107 * @note must be called only once!
109 const char* resultAsString() noexcept
111 const uint8_t* const hash
= resultAsHash();
113 for (int i
=0; i
<20; ++i
)
114 std::snprintf(resultstr
+ (i
* 2), 3, "%02x", hash
[i
]);
116 resultstr
[40] = '\0';
122 void _addUncounted(const uint8_t data
) noexcept
124 #ifdef CARLA_SHA1_BIG_ENDIAN
125 buffer
.u8
[bufferOffset
] = data
;
127 buffer
.u8
[bufferOffset
^ 3] = data
;
129 if (++bufferOffset
== BLOCK_LENGTH
)
136 void _hashBlock() noexcept
138 uint32_t a
= state
[0];
139 uint32_t b
= state
[1];
140 uint32_t c
= state
[2];
141 uint32_t d
= state
[3];
142 uint32_t e
= state
[4];
145 for (uint8_t i
=0; i
<80; ++i
)
149 t
= buffer
.u32
[(i
+ 13) & 15]
150 ^ buffer
.u32
[(i
+ 8) & 15]
151 ^ buffer
.u32
[(i
+ 2) & 15]
152 ^ buffer
.u32
[i
& 15];
153 buffer
.u32
[i
& 15] = _rol32(t
, 1);
157 t
= (d
^ (b
& (c
^ d
))) + 0x5a827999;
161 t
= (b
^ c
^ d
) + 0x6ed9eba1;
165 t
= ((b
& c
) | (d
& (b
| c
))) + 0x8f1bbcdc;
169 t
= (b
^ c
^ d
) + 0xca62c1d6;
171 t
+= _rol32(a
, 5) + e
+ buffer
.u32
[i
& 15];
186 // Implement SHA-1 padding (fips180-2 ยง5.1.1)
189 // Pad with 0x80 followed by 0x00 until the end of the block
191 while (bufferOffset
!= 56) _addUncounted(0x00);
193 // Append length in the last 8 bytes
194 _addUncounted(0); // We're only using 32 bit lengths
195 _addUncounted(0); // But SHA-1 supports 64 bit lengths
196 _addUncounted(0); // So zero pad the top bits
197 _addUncounted(byteCount
>> 29); // Shifting to multiply by 8
198 _addUncounted(byteCount
>> 21); // as SHA-1 supports bitstreams as well as
199 _addUncounted(byteCount
>> 13); // byte.
200 _addUncounted(byteCount
>> 5);
201 _addUncounted(byteCount
<< 3);
204 static uint32_t _rol32(const uint32_t number
, const uint8_t bits
) noexcept
206 return (number
<< bits
) | (number
>> (32 - bits
));
210 #endif // CARLA_SHA1_UTILS_HPP_INCLUDED