File indexing completed on 2025-01-18 09:29:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_BEAST_DETAIL_SHA1_IPP
0011 #define BOOST_BEAST_DETAIL_SHA1_IPP
0012
0013 #include <boost/beast/core/detail/sha1.hpp>
0014
0015 #include <algorithm>
0016 #include <cstdint>
0017 #include <cstring>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 namespace boost {
0030 namespace beast {
0031 namespace detail {
0032
0033 namespace sha1 {
0034
0035 inline
0036 std::uint32_t
0037 rol(std::uint32_t value, std::size_t bits)
0038 {
0039 return (value << bits) | (value >> (32 - bits));
0040 }
0041
0042 inline
0043 std::uint32_t
0044 blk(std::uint32_t block[BLOCK_INTS], std::size_t i)
0045 {
0046 return rol(
0047 block[(i+13)&15] ^ block[(i+8)&15] ^
0048 block[(i+2)&15] ^ block[i], 1);
0049 }
0050
0051 inline
0052 void
0053 R0(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
0054 std::uint32_t &w, std::uint32_t x, std::uint32_t y,
0055 std::uint32_t &z, std::size_t i)
0056 {
0057 z += ((w&(x^y))^y) + block[i] + 0x5a827999 + rol(v, 5);
0058 w = rol(w, 30);
0059 }
0060
0061
0062 inline
0063 void
0064 R1(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
0065 std::uint32_t &w, std::uint32_t x, std::uint32_t y,
0066 std::uint32_t &z, std::size_t i)
0067 {
0068 block[i] = blk(block, i);
0069 z += ((w&(x^y))^y) + block[i] + 0x5a827999 + rol(v, 5);
0070 w = rol(w, 30);
0071 }
0072
0073 inline
0074 void
0075 R2(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
0076 std::uint32_t &w, std::uint32_t x, std::uint32_t y,
0077 std::uint32_t &z, std::size_t i)
0078 {
0079 block[i] = blk(block, i);
0080 z += (w^x^y) + block[i] + 0x6ed9eba1 + rol(v, 5);
0081 w = rol(w, 30);
0082 }
0083
0084 inline
0085 void
0086 R3(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
0087 std::uint32_t &w, std::uint32_t x, std::uint32_t y,
0088 std::uint32_t &z, std::size_t i)
0089 {
0090 block[i] = blk(block, i);
0091 z += (((w|x)&y)|(w&x)) + block[i] + 0x8f1bbcdc + rol(v, 5);
0092 w = rol(w, 30);
0093 }
0094
0095 inline
0096 void
0097 R4(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
0098 std::uint32_t &w, std::uint32_t x, std::uint32_t y,
0099 std::uint32_t &z, std::size_t i)
0100 {
0101 block[i] = blk(block, i);
0102 z += (w^x^y) + block[i] + 0xca62c1d6 + rol(v, 5);
0103 w = rol(w, 30);
0104 }
0105
0106 inline
0107 void
0108 make_block(std::uint8_t const* p,
0109 std::uint32_t block[BLOCK_INTS])
0110 {
0111 for(std::size_t i = 0; i < BLOCK_INTS; i++)
0112 block[i] =
0113 (static_cast<std::uint32_t>(p[4*i+3])) |
0114 (static_cast<std::uint32_t>(p[4*i+2]))<< 8 |
0115 (static_cast<std::uint32_t>(p[4*i+1]))<<16 |
0116 (static_cast<std::uint32_t>(p[4*i+0]))<<24;
0117 }
0118
0119 inline
0120 void
0121 transform(
0122 std::uint32_t digest[], std::uint32_t block[BLOCK_INTS])
0123 {
0124 std::uint32_t a = digest[0];
0125 std::uint32_t b = digest[1];
0126 std::uint32_t c = digest[2];
0127 std::uint32_t d = digest[3];
0128 std::uint32_t e = digest[4];
0129
0130 R0(block, a, b, c, d, e, 0);
0131 R0(block, e, a, b, c, d, 1);
0132 R0(block, d, e, a, b, c, 2);
0133 R0(block, c, d, e, a, b, 3);
0134 R0(block, b, c, d, e, a, 4);
0135 R0(block, a, b, c, d, e, 5);
0136 R0(block, e, a, b, c, d, 6);
0137 R0(block, d, e, a, b, c, 7);
0138 R0(block, c, d, e, a, b, 8);
0139 R0(block, b, c, d, e, a, 9);
0140 R0(block, a, b, c, d, e, 10);
0141 R0(block, e, a, b, c, d, 11);
0142 R0(block, d, e, a, b, c, 12);
0143 R0(block, c, d, e, a, b, 13);
0144 R0(block, b, c, d, e, a, 14);
0145 R0(block, a, b, c, d, e, 15);
0146 R1(block, e, a, b, c, d, 0);
0147 R1(block, d, e, a, b, c, 1);
0148 R1(block, c, d, e, a, b, 2);
0149 R1(block, b, c, d, e, a, 3);
0150 R2(block, a, b, c, d, e, 4);
0151 R2(block, e, a, b, c, d, 5);
0152 R2(block, d, e, a, b, c, 6);
0153 R2(block, c, d, e, a, b, 7);
0154 R2(block, b, c, d, e, a, 8);
0155 R2(block, a, b, c, d, e, 9);
0156 R2(block, e, a, b, c, d, 10);
0157 R2(block, d, e, a, b, c, 11);
0158 R2(block, c, d, e, a, b, 12);
0159 R2(block, b, c, d, e, a, 13);
0160 R2(block, a, b, c, d, e, 14);
0161 R2(block, e, a, b, c, d, 15);
0162 R2(block, d, e, a, b, c, 0);
0163 R2(block, c, d, e, a, b, 1);
0164 R2(block, b, c, d, e, a, 2);
0165 R2(block, a, b, c, d, e, 3);
0166 R2(block, e, a, b, c, d, 4);
0167 R2(block, d, e, a, b, c, 5);
0168 R2(block, c, d, e, a, b, 6);
0169 R2(block, b, c, d, e, a, 7);
0170 R3(block, a, b, c, d, e, 8);
0171 R3(block, e, a, b, c, d, 9);
0172 R3(block, d, e, a, b, c, 10);
0173 R3(block, c, d, e, a, b, 11);
0174 R3(block, b, c, d, e, a, 12);
0175 R3(block, a, b, c, d, e, 13);
0176 R3(block, e, a, b, c, d, 14);
0177 R3(block, d, e, a, b, c, 15);
0178 R3(block, c, d, e, a, b, 0);
0179 R3(block, b, c, d, e, a, 1);
0180 R3(block, a, b, c, d, e, 2);
0181 R3(block, e, a, b, c, d, 3);
0182 R3(block, d, e, a, b, c, 4);
0183 R3(block, c, d, e, a, b, 5);
0184 R3(block, b, c, d, e, a, 6);
0185 R3(block, a, b, c, d, e, 7);
0186 R3(block, e, a, b, c, d, 8);
0187 R3(block, d, e, a, b, c, 9);
0188 R3(block, c, d, e, a, b, 10);
0189 R3(block, b, c, d, e, a, 11);
0190 R4(block, a, b, c, d, e, 12);
0191 R4(block, e, a, b, c, d, 13);
0192 R4(block, d, e, a, b, c, 14);
0193 R4(block, c, d, e, a, b, 15);
0194 R4(block, b, c, d, e, a, 0);
0195 R4(block, a, b, c, d, e, 1);
0196 R4(block, e, a, b, c, d, 2);
0197 R4(block, d, e, a, b, c, 3);
0198 R4(block, c, d, e, a, b, 4);
0199 R4(block, b, c, d, e, a, 5);
0200 R4(block, a, b, c, d, e, 6);
0201 R4(block, e, a, b, c, d, 7);
0202 R4(block, d, e, a, b, c, 8);
0203 R4(block, c, d, e, a, b, 9);
0204 R4(block, b, c, d, e, a, 10);
0205 R4(block, a, b, c, d, e, 11);
0206 R4(block, e, a, b, c, d, 12);
0207 R4(block, d, e, a, b, c, 13);
0208 R4(block, c, d, e, a, b, 14);
0209 R4(block, b, c, d, e, a, 15);
0210
0211 digest[0] += a;
0212 digest[1] += b;
0213 digest[2] += c;
0214 digest[3] += d;
0215 digest[4] += e;
0216 }
0217
0218 }
0219
0220 void
0221 init(sha1_context& ctx) noexcept
0222 {
0223 ctx.buflen = 0;
0224 ctx.blocks = 0;
0225 ctx.digest[0] = 0x67452301;
0226 ctx.digest[1] = 0xefcdab89;
0227 ctx.digest[2] = 0x98badcfe;
0228 ctx.digest[3] = 0x10325476;
0229 ctx.digest[4] = 0xc3d2e1f0;
0230 }
0231
0232 void
0233 update(
0234 sha1_context& ctx,
0235 void const* message,
0236 std::size_t size) noexcept
0237 {
0238 auto p = static_cast<
0239 std::uint8_t const*>(message);
0240 for(;;)
0241 {
0242 auto const n = (std::min)(
0243 size, sizeof(ctx.buf) - ctx.buflen);
0244 std::memcpy(ctx.buf + ctx.buflen, p, n);
0245 ctx.buflen += n;
0246 if(ctx.buflen != 64)
0247 return;
0248 p += n;
0249 size -= n;
0250 ctx.buflen = 0;
0251 std::uint32_t block[sha1::BLOCK_INTS];
0252 sha1::make_block(ctx.buf, block);
0253 sha1::transform(ctx.digest, block);
0254 ++ctx.blocks;
0255 }
0256 }
0257
0258 void
0259 finish(
0260 sha1_context& ctx,
0261 void* digest) noexcept
0262 {
0263 using sha1::BLOCK_INTS;
0264 using sha1::BLOCK_BYTES;
0265
0266 std::uint64_t total_bits =
0267 (ctx.blocks*64 + ctx.buflen) * 8;
0268
0269 ctx.buf[ctx.buflen++] = 0x80;
0270 auto const buflen = ctx.buflen;
0271 while(ctx.buflen < 64)
0272 ctx.buf[ctx.buflen++] = 0x00;
0273 std::uint32_t block[BLOCK_INTS];
0274 sha1::make_block(ctx.buf, block);
0275 if(buflen > BLOCK_BYTES - 8)
0276 {
0277 sha1::transform(ctx.digest, block);
0278 for(size_t i = 0; i < BLOCK_INTS - 2; i++)
0279 block[i] = 0;
0280 }
0281
0282
0283 block[BLOCK_INTS - 1] = total_bits & 0xffffffff;
0284 block[BLOCK_INTS - 2] = (total_bits >> 32);
0285 sha1::transform(ctx.digest, block);
0286 for(std::size_t i = 0; i < sha1::DIGEST_BYTES/4; i++)
0287 {
0288 std::uint8_t* d =
0289 static_cast<std::uint8_t*>(digest) + 4 * i;
0290 d[3] = ctx.digest[i] & 0xff;
0291 d[2] = (ctx.digest[i] >> 8) & 0xff;
0292 d[1] = (ctx.digest[i] >> 16) & 0xff;
0293 d[0] = (ctx.digest[i] >> 24) & 0xff;
0294 }
0295 }
0296
0297 }
0298 }
0299 }
0300
0301 #endif