LCOV - code coverage report
Current view: top level - core/core/string - SPSha2.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 352 369 95.4 %
Date: 2024-05-12 00:16:13 Functions: 62 62 100.0 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : /*
      25             :  * Sha2 source code in public domain
      26             :  * */
      27             : 
      28             : #include "SPCoreCrypto.h"
      29             : 
      30             : namespace STAPPLER_VERSIONIZED sha256 {
      31             : 
      32             : using sha256_state = stappler::crypto::Sha256::_Ctx;
      33             : 
      34             : typedef uint32_t u32;
      35             : typedef uint64_t u64;
      36             : 
      37             : static const u32 K[64] = {
      38             :     0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
      39             :     0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
      40             :     0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
      41             :     0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
      42             :     0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
      43             :     0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
      44             :     0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
      45             :     0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
      46             :     0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
      47             :     0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
      48             :     0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
      49             :     0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
      50             :     0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
      51             : };
      52             : 
      53        1200 : static u32 sha_min(u32 x, u32 y) {
      54        1200 :     return x < y ? x : y;
      55             : }
      56             : 
      57      122000 : static u32 load32(const unsigned char* y) {
      58      122000 :     return (u32(y[0]) << 24) | (u32(y[1]) << 16) | (u32(y[2]) << 8) | (u32(y[3]) << 0);
      59             : }
      60             : 
      61         875 : static void store64(u64 x, unsigned char* y) {
      62        7875 :     for(int i = 0; i != 8; ++i)
      63        7000 :         y[i] = (x >> ((7-i) * 8)) & 255;
      64         875 : }
      65             : 
      66        7000 : static void store32(u32 x, unsigned char* y) {
      67       35000 :     for(int i = 0; i != 4; ++i)
      68       28000 :         y[i] = (x >> ((3-i) * 8)) & 255;
      69        7000 : }
      70             : 
      71      488000 : static u32 Ch(u32 x, u32 y, u32 z)  { return z ^ (x & (y ^ z)); }
      72      488000 : static u32 Maj(u32 x, u32 y, u32 z) { return ((x | y) & z) | (x & y); }
      73     4392000 : static u32 Rot(u32 x, u32 n)        { return (x >> (n & 31)) | (x << (32 - (n & 31))); }
      74      732000 : static u32 Sh(u32 x, u32 n)         { return x >> n; }
      75      488000 : static u32 Sigma0(u32 x)            { return Rot(x, 2) ^ Rot(x, 13) ^ Rot(x, 22); }
      76      488000 : static u32 Sigma1(u32 x)            { return Rot(x, 6) ^ Rot(x, 11) ^ Rot(x, 25); }
      77      366000 : static u32 Gamma0(u32 x)            { return Rot(x, 7) ^ Rot(x, 18) ^ Sh(x, 3); }
      78      366000 : static u32 Gamma1(u32 x)            { return Rot(x, 17) ^ Rot(x, 19) ^ Sh(x, 10); }
      79             : 
      80        7625 : static void sha_compress(sha256_state& md, const unsigned char* buf) {
      81             :     u32 S[8], W[64], t0, t1, t;
      82             : 
      83             :     // Copy state into S
      84       68625 :     for(int i = 0; i < 8; i++)
      85       61000 :         S[i] = md.state[i];
      86             : 
      87             :     // Copy the state into 512-bits into W[0..15]
      88      129625 :     for(int i = 0; i < 16; i++)
      89      122000 :         W[i] = load32(buf + (4*i));
      90             : 
      91             :     // Fill W[16..63]
      92      373625 :     for(int i = 16; i < 64; i++)
      93      366000 :         W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
      94             : 
      95             :     // Compress
      96      488000 :     auto RND = [&](u32 a, u32 b, u32 c, u32& d, u32 e, u32 f, u32 g, u32& h, u32 i) {
      97      488000 :         t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];
      98      488000 :         t1 = Sigma0(a) + Maj(a, b, c);
      99      488000 :         d += t0;
     100      488000 :         h  = t0 + t1;
     101      495625 :     };
     102             : 
     103      495625 :     for(int i = 0; i < 64; ++i) {
     104      488000 :         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
     105      488000 :         t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
     106      488000 :         S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
     107             :     }
     108             : 
     109             :     // Feedback
     110       68625 :     for(int i = 0; i < 8; i++)
     111       61000 :         md.state[i] = md.state[i] + S[i];
     112        7625 : }
     113             : 
     114             : // Public interface
     115             : 
     116        1100 : void sha_init(sha256_state& md) {
     117        1100 :     md.curlen = 0;
     118        1100 :     md.length = 0;
     119        1100 :     md.state[0] = 0x6A09E667UL;
     120        1100 :     md.state[1] = 0xBB67AE85UL;
     121        1100 :     md.state[2] = 0x3C6EF372UL;
     122        1100 :     md.state[3] = 0xA54FF53AUL;
     123        1100 :     md.state[4] = 0x510E527FUL;
     124        1100 :     md.state[5] = 0x9B05688CUL;
     125        1100 :     md.state[6] = 0x1F83D9ABUL;
     126        1100 :     md.state[7] = 0x5BE0CD19UL;
     127        1100 : }
     128             : 
     129        1500 : static void sha_process(sha256_state& md, const void* src, u32 inlen) {
     130        1500 :     const u32 block_size = sizeof(sha256_state::buf);
     131        1500 :     auto in = static_cast<const unsigned char*>(src);
     132             : 
     133        9300 :     while(inlen > 0) {
     134        7800 :         if(md.curlen == 0 && inlen >= block_size) {
     135        6600 :             sha_compress(md, in);
     136        6600 :             md.length += block_size * 8;
     137        6600 :             in        += block_size;
     138        6600 :             inlen     -= block_size;
     139             :         } else {
     140        1200 :             u32 n = sha_min(inlen, (block_size - md.curlen));
     141        1200 :             memcpy(md.buf + md.curlen, in, n);
     142        1200 :             md.curlen += n;
     143        1200 :             in        += n;
     144        1200 :             inlen     -= n;
     145             : 
     146        1200 :             if(md.curlen == block_size) {
     147         150 :                 sha_compress(md, md.buf);
     148         150 :                 md.length += 8*block_size;
     149         150 :                 md.curlen = 0;
     150             :             }
     151             :         }
     152             :     }
     153        1500 : }
     154             : 
     155         875 : static void sha_done(sha256_state& md, void* out) {
     156             :     // Increase the length of the message
     157         875 :     md.length += md.curlen * 8;
     158             : 
     159             :     // Append the '1' bit
     160         875 :     md.buf[md.curlen++] = static_cast<unsigned char>(0x80);
     161             : 
     162             :     // If the length is currently above 56 bytes we append zeros then compress.
     163             :     // Then we can fall back to padding zeros and length encoding like normal.
     164         875 :     if(md.curlen > 56) {
     165           0 :         while(md.curlen < 64)
     166           0 :             md.buf[md.curlen++] = 0;
     167           0 :         sha_compress(md, md.buf);
     168           0 :         md.curlen = 0;
     169             :     }
     170             : 
     171             :     // Pad upto 56 bytes of zeroes
     172       22100 :     while(md.curlen < 56)
     173       21225 :         md.buf[md.curlen++] = 0;
     174             : 
     175             :     // Store length
     176         875 :     store64(md.length, md.buf+56);
     177         875 :     sha_compress(md, md.buf);
     178             : 
     179             :     // Copy output
     180        7875 :     for(int i = 0; i < 8; i++)
     181        7000 :         store32(md.state[i], static_cast<unsigned char*>(out)+(4*i));
     182         875 : }
     183             : 
     184             : }
     185             : 
     186             : namespace STAPPLER_VERSIONIZED sha512 {
     187             : 
     188             : using sha512_state = stappler::crypto::Sha512::_Ctx;
     189             : 
     190             : typedef uint32_t u32;
     191             : typedef uint64_t u64;
     192             : 
     193             : static const u64 K[80] =
     194             : {
     195             :     0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL,
     196             :     0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
     197             :     0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
     198             :     0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
     199             :     0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL,
     200             :     0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
     201             :     0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL,
     202             :     0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
     203             :     0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
     204             :     0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
     205             :     0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL,
     206             :     0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
     207             :     0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL,
     208             :     0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
     209             :     0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
     210             :     0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
     211             : };
     212             : 
     213        4375 : static u32 sha_min(u32 x, u32 y) {
     214        4375 :     return x < y ? x : y;
     215             : }
     216             : 
     217       20250 : static void store64(u64 x, unsigned char* y) {
     218      182250 :     for(int i = 0; i != 8; ++i)
     219      162000 :         y[i] = (x >> ((7-i) * 8)) & 255;
     220       20250 : }
     221             : 
     222      101600 : static u64 load64(const unsigned char* y) {
     223      101600 :     u64 res = 0;
     224      914400 :     for(int i = 0; i != 8; ++i)
     225      812800 :         res |= u64(y[i]) << ((7-i) * 8);
     226      101600 :     return res;
     227             : }
     228             : 
     229      508000 : static u64 Ch(u64 x, u64 y, u64 z)  { return z ^ (x & (y ^ z)); }
     230      508000 : static u64 Maj(u64 x, u64 y, u64 z) { return ((x | y) & z) | (x & y); }
     231     4673600 : static u64 Rot(u64 x, u64 n)        { return (x >> (n & 63)) | (x << (64 - (n & 63))); }
     232      812800 : static u64 Sh(u64 x, u64 n)         { return x >> n; }
     233      508000 : static u64 Sigma0(u64 x)            { return Rot(x, 28) ^ Rot(x, 34) ^ Rot(x, 39); }
     234      508000 : static u64 Sigma1(u64 x)            { return Rot(x, 14) ^ Rot(x, 18) ^ Rot(x, 41); }
     235      406400 : static u64 Gamma0(u64 x)            { return Rot(x, 1) ^ Rot(x, 8) ^ Sh(x, 7); }
     236      406400 : static u64 Gamma1(u64 x)            { return Rot(x, 19) ^ Rot(x, 61) ^ Sh(x, 6); }
     237             : 
     238        6350 : static void sha_compress(sha512_state& md, const unsigned char *buf) {
     239             :     u64 S[8], W[80], t0, t1;
     240             : 
     241             :     // Copy state into S
     242       57150 :     for(int i = 0; i < 8; i++)
     243       50800 :         S[i] = md.state[i];
     244             : 
     245             :     // Copy the state into 1024-bits into W[0..15]
     246      107950 :     for(int i = 0; i < 16; i++)
     247      101600 :         W[i] = load64(buf + (8*i));
     248             : 
     249             :     // Fill W[16..79]
     250      412750 :     for(int i = 16; i < 80; i++)
     251      406400 :         W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
     252             : 
     253             :     // Compress
     254      508000 :     auto RND = [&](u64 a, u64 b, u64 c, u64& d, u64 e, u64 f, u64 g, u64& h, u64 i) {
     255      508000 :         t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];
     256      508000 :         t1 = Sigma0(a) + Maj(a, b, c);
     257      508000 :         d += t0;
     258      508000 :         h  = t0 + t1;
     259      514350 :     };
     260             : 
     261       69850 :     for(int i = 0; i < 80; i += 8) {
     262       63500 :         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
     263       63500 :         RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
     264       63500 :         RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
     265       63500 :         RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
     266       63500 :         RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
     267       63500 :         RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
     268       63500 :         RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
     269       63500 :         RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
     270             :     }
     271             : 
     272             :      // Feedback
     273       57150 :      for(int i = 0; i < 8; i++)
     274       50800 :          md.state[i] = md.state[i] + S[i];
     275        6350 : }
     276             : 
     277             : // Public interface
     278             : 
     279        2350 : static void sha_init(sha512_state& md) {
     280        2350 :     md.curlen = 0;
     281        2350 :     md.length = 0;
     282        2350 :     md.state[0] = 0x6a09e667f3bcc908ULL;
     283        2350 :     md.state[1] = 0xbb67ae8584caa73bULL;
     284        2350 :     md.state[2] = 0x3c6ef372fe94f82bULL;
     285        2350 :     md.state[3] = 0xa54ff53a5f1d36f1ULL;
     286        2350 :     md.state[4] = 0x510e527fade682d1ULL;
     287        2350 :     md.state[5] = 0x9b05688c2b3e6c1fULL;
     288        2350 :     md.state[6] = 0x1f83d9abfb41bd6bULL;
     289        2350 :     md.state[7] = 0x5be0cd19137e2179ULL;
     290        2350 : }
     291             : 
     292        4775 : static void sha_process(sha512_state& md, const void* src, u32 inlen) {
     293        4775 :     const u32 block_size = sizeof(sha512_state::buf);
     294        4775 :     auto in = static_cast<const unsigned char*>(src);
     295             : 
     296       13175 :     while (inlen > 0) {
     297        8400 :         if(md.curlen == 0 && inlen >= block_size) {
     298        4025 :             sha_compress(md, in);
     299        4025 :             md.length += block_size * 8;
     300        4025 :             in        += block_size;
     301        4025 :             inlen     -= block_size;
     302             :         } else {
     303        4375 :             u32 n = sha_min(inlen, (block_size - md.curlen));
     304        4375 :             memcpy(md.buf + md.curlen, in, n);
     305        4375 :             md.curlen += n;
     306        4375 :             in        += n;
     307        4375 :             inlen     -= n;
     308             : 
     309        4375 :             if(md.curlen == block_size) {
     310          75 :                 sha_compress(md, md.buf);
     311          75 :                 md.length += 8*block_size;
     312          75 :                 md.curlen = 0;
     313             :             }
     314             :         }
     315             :     }
     316        4775 : }
     317             : 
     318        2250 : static void sha_done(sha512_state& md, void *out) {
     319             :     // Increase the length of the message
     320        2250 :     md.length += md.curlen * 8ULL;
     321             : 
     322             :     // Append the '1' bit
     323        2250 :     md.buf[md.curlen++] = static_cast<unsigned char>(0x80);
     324             : 
     325             :     // If the length is currently above 112 bytes we append zeros then compress.
     326             :     // Then we can fall back to padding zeros and length encoding like normal.
     327        2250 :     if(md.curlen > 112) {
     328           0 :         while(md.curlen < 128)
     329           0 :             md.buf[md.curlen++] = 0;
     330           0 :         sha_compress(md, md.buf);
     331           0 :         md.curlen = 0;
     332             :     }
     333             : 
     334             :     // Pad upto 120 bytes of zeroes
     335             :     // note: that from 112 to 120 is the 64 MSB of the length.  We assume that
     336             :     // you won't hash 2^64 bits of data... :-)
     337      142400 :     while(md.curlen < 120)
     338      140150 :         md.buf[md.curlen++] = 0;
     339             : 
     340             :     // Store length
     341        2250 :     store64(md.length, md.buf+120);
     342        2250 :     sha_compress(md, md.buf);
     343             : 
     344             :     // Copy output
     345       20250 :     for(int i = 0; i < 8; i++)
     346       18000 :         store64(md.state[i], static_cast<unsigned char*>(out)+(8*i));
     347        2250 : }
     348             : 
     349             : }
     350             : 
     351             : 
     352             : namespace STAPPLER_VERSIONIZED sha1 {
     353             : 
     354             : using Sha1 = stappler::crypto::Sha1;
     355             : 
     356             : /* SHA f()-functions */
     357             : #define f1(x,y,z)       ((x & y) | (~x & z))
     358             : #define f2(x,y,z)       (x ^ y ^ z)
     359             : #define f3(x,y,z)       ((x & y) | (x & z) | (y & z))
     360             : #define f4(x,y,z)       (x ^ y ^ z)
     361             : 
     362             : /* SHA constants */
     363             : static constexpr uint32_t CONST1 = 0x5a827999L;
     364             : static constexpr uint32_t CONST2 = 0x6ed9eba1L;
     365             : static constexpr uint32_t CONST3 = 0x8f1bbcdcL;
     366             : static constexpr uint32_t CONST4 = 0xca62c1d6L;
     367             : 
     368             : static constexpr uint32_t SHA_BLOCKSIZE = 64;
     369             : 
     370             : /* 32-bit rotate */
     371             : 
     372             : #define ROT32(x,n)      ((x << n) | (x >> (32 - n)))
     373             : 
     374             : #define FUNC(n,i) \
     375             :         temp = ROT32(A,5) + f##n(B,C,D) + E + W[i] + CONST##n; \
     376             :         E = D; D = C; C = ROT32(B,30); B = A; A = temp
     377             : 
     378             : /* do SHA transformation */
     379         200 : static void sha_transform(stappler::crypto::Sha1::_Ctx &sha_info) {
     380             :         int i;
     381             :         uint32_t temp, A, B, C, D, E, W[80];
     382             : 
     383        3400 :         for (i = 0; i < 16; ++i) {
     384        3200 :                 W[i] = sha_info.data[i];
     385             :         }
     386       13000 :         for (i = 16; i < 80; ++i) {
     387       12800 :                 W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
     388             : 
     389       12800 :                 W[i] = ROT32(W[i], 1);
     390             :         }
     391             : 
     392         200 :         A = sha_info.digest[0];
     393         200 :         B = sha_info.digest[1];
     394         200 :         C = sha_info.digest[2];
     395         200 :         D = sha_info.digest[3];
     396         200 :         E = sha_info.digest[4];
     397             : 
     398         200 :         FUNC(1, 0);  FUNC(1, 1);  FUNC(1, 2);  FUNC(1, 3);  FUNC(1, 4);
     399         200 :         FUNC(1, 5);  FUNC(1, 6);  FUNC(1, 7);  FUNC(1, 8);  FUNC(1, 9);
     400         200 :         FUNC(1,10);  FUNC(1,11);  FUNC(1,12);  FUNC(1,13);  FUNC(1,14);
     401         200 :         FUNC(1,15);  FUNC(1,16);  FUNC(1,17);  FUNC(1,18);  FUNC(1,19);
     402             : 
     403         200 :         FUNC(2,20);  FUNC(2,21);  FUNC(2,22);  FUNC(2,23);  FUNC(2,24);
     404         200 :         FUNC(2,25);  FUNC(2,26);  FUNC(2,27);  FUNC(2,28);  FUNC(2,29);
     405         200 :         FUNC(2,30);  FUNC(2,31);  FUNC(2,32);  FUNC(2,33);  FUNC(2,34);
     406         200 :         FUNC(2,35);  FUNC(2,36);  FUNC(2,37);  FUNC(2,38);  FUNC(2,39);
     407             : 
     408         200 :         FUNC(3,40);  FUNC(3,41);  FUNC(3,42);  FUNC(3,43);  FUNC(3,44);
     409         200 :         FUNC(3,45);  FUNC(3,46);  FUNC(3,47);  FUNC(3,48);  FUNC(3,49);
     410         200 :         FUNC(3,50);  FUNC(3,51);  FUNC(3,52);  FUNC(3,53);  FUNC(3,54);
     411         200 :         FUNC(3,55);  FUNC(3,56);  FUNC(3,57);  FUNC(3,58);  FUNC(3,59);
     412             : 
     413         200 :         FUNC(4,60);  FUNC(4,61);  FUNC(4,62);  FUNC(4,63);  FUNC(4,64);
     414         200 :         FUNC(4,65);  FUNC(4,66);  FUNC(4,67);  FUNC(4,68);  FUNC(4,69);
     415         200 :         FUNC(4,70);  FUNC(4,71);  FUNC(4,72);  FUNC(4,73);  FUNC(4,74);
     416         200 :         FUNC(4,75);  FUNC(4,76);  FUNC(4,77);  FUNC(4,78);  FUNC(4,79);
     417             : 
     418         200 :         sha_info.digest[0] += A;
     419         200 :         sha_info.digest[1] += B;
     420         200 :         sha_info.digest[2] += C;
     421         200 :         sha_info.digest[3] += D;
     422         200 :         sha_info.digest[4] += E;
     423         200 : }
     424             : 
     425             : /* count is the number of bytes to do an endian flip */
     426         200 : static void maybe_byte_reverse(uint32_t *buffer, int count) {
     427             :         int i;
     428             :         uint8_t ct[4], *cp;
     429             : 
     430             :         /* do the swap only if it is little endian */
     431             :         if constexpr (stappler::Endian::Host == stappler::Endian::Little) {
     432         200 :                 count /= sizeof(uint32_t);
     433         200 :                 cp = reinterpret_cast<uint8_t *>(buffer);
     434        3400 :                 for (i = 0; i < count; ++i) {
     435        3200 :                         ct[0] = cp[0];
     436        3200 :                         ct[1] = cp[1];
     437        3200 :                         ct[2] = cp[2];
     438        3200 :                         ct[3] = cp[3];
     439        3200 :                         cp[0] = ct[3];
     440        3200 :                         cp[1] = ct[2];
     441        3200 :                         cp[2] = ct[1];
     442        3200 :                         cp[3] = ct[0];
     443        3200 :                         cp += sizeof(uint32_t);
     444             :                 }
     445             :         }
     446         200 : }
     447             : 
     448         225 : void sha_init(Sha1::_Ctx &sha_info) {
     449         225 :         sha_info.digest[0] = 0x67452301L;
     450         225 :         sha_info.digest[1] = 0xefcdab89L;
     451         225 :         sha_info.digest[2] = 0x98badcfeL;
     452         225 :         sha_info.digest[3] = 0x10325476L;
     453         225 :         sha_info.digest[4] = 0xc3d2e1f0L;
     454         225 :         sha_info.count_lo = 0L;
     455         225 :         sha_info.count_hi = 0L;
     456         225 :         sha_info.local = 0;
     457         225 : }
     458             : 
     459         250 : void sha_process(Sha1::_Ctx &sha_info, const uint8_t *buffer, uint32_t count) {
     460             :         unsigned int i;
     461             : 
     462         250 :         if ((sha_info.count_lo + (count << 3)) < sha_info.count_lo) {
     463           0 :                 ++sha_info.count_hi;
     464             :         }
     465         250 :         sha_info.count_lo += count << 3;
     466         250 :         sha_info.count_hi += count >> 29;
     467         250 :         if (sha_info.local) {
     468         100 :                 i = SHA_BLOCKSIZE - sha_info.local;
     469         100 :                 if (i > count) {
     470         100 :                         i = count;
     471             :                 }
     472         100 :                 memcpy(reinterpret_cast<uint8_t *>(sha_info.data) + sha_info.local, buffer, i);
     473         100 :                 count -= i;
     474         100 :                 buffer += i;
     475         100 :                 sha_info.local += i;
     476         100 :                 if (sha_info.local == SHA_BLOCKSIZE) {
     477           0 :                         maybe_byte_reverse(sha_info.data, SHA_BLOCKSIZE);
     478           0 :                         sha_transform(sha_info);
     479             :                 } else {
     480         100 :                         return;
     481             :                 }
     482             :         }
     483         150 :         while (count >= SHA_BLOCKSIZE) {
     484           0 :                 memcpy(sha_info.data, buffer, SHA_BLOCKSIZE);
     485           0 :                 buffer += SHA_BLOCKSIZE;
     486           0 :                 count -= SHA_BLOCKSIZE;
     487           0 :                 maybe_byte_reverse(sha_info.data, SHA_BLOCKSIZE);
     488           0 :                 sha_transform(sha_info);
     489             :         }
     490         150 :         memcpy(sha_info.data, buffer, count);
     491         150 :         sha_info.local = count;
     492             : }
     493             : 
     494         150 : void sha_done(stappler::crypto::Sha1::_Ctx &sha_info, uint8_t *digest) {
     495             :         int count, i, j;
     496             :         uint32_t lo_bit_count, hi_bit_count, k;
     497             : 
     498         150 :         lo_bit_count = sha_info.count_lo;
     499         150 :         hi_bit_count = sha_info.count_hi;
     500         150 :         count = int32_t((lo_bit_count >> 3) & 0x3f);
     501         150 :         reinterpret_cast<uint8_t *>(sha_info.data)[count++] = 0x80;
     502         150 :         if (count > int(SHA_BLOCKSIZE - 8)) {
     503          50 :                 memset(reinterpret_cast<uint8_t *>(sha_info.data) + count, 0, SHA_BLOCKSIZE - count);
     504          50 :                 maybe_byte_reverse(sha_info.data, SHA_BLOCKSIZE);
     505          50 :                 sha_transform(sha_info);
     506          50 :                 memset(reinterpret_cast<uint8_t *>(sha_info.data), 0, SHA_BLOCKSIZE - 8);
     507             :         } else {
     508         100 :                 memset(reinterpret_cast<uint8_t *>(sha_info.data) + count, 0,
     509         100 :                 SHA_BLOCKSIZE - 8 - count);
     510             :         }
     511         150 :         maybe_byte_reverse(sha_info.data, SHA_BLOCKSIZE);
     512         150 :         sha_info.data[14] = hi_bit_count;
     513         150 :         sha_info.data[15] = lo_bit_count;
     514         150 :         sha_transform(sha_info);
     515             : 
     516         900 :         for (i = 0, j = 0; j < int(stappler::crypto::Sha1::Length); i++) {
     517         750 :                 k = sha_info.digest[i];
     518         750 :                 digest[j++] = uint8_t((k >> 24) & 0xff);
     519         750 :                 digest[j++] = uint8_t((k >> 16) & 0xff);
     520         750 :                 digest[j++] = uint8_t((k >> 8) & 0xff);
     521         750 :                 digest[j++] = uint8_t(k & 0xff);
     522             :         }
     523         150 : }
     524             : 
     525             : }
     526             : 
     527             : 
     528             : namespace STAPPLER_VERSIONIZED stappler::crypto {
     529             : 
     530          25 : Sha1::Buf Sha1::make(const CoderSource &source, const StringView &salt) {
     531          25 :         return Sha1().update(salt.empty()?StringView(SP_SECURE_KEY):salt).update(source).final();
     532             : }
     533             : 
     534          25 : Sha1::Buf Sha1::hmac(const CoderSource &data, const CoderSource &key) {
     535             :         Buf ret;
     536          25 :         std::array<uint8_t, Length * 2> keyData = { 0 };
     537             : 
     538          25 :         Sha1 shaCtx;
     539          25 :         if (key.size() > Length * 2) {
     540           0 :                 shaCtx.update(key).final(keyData.data());
     541             :         } else {
     542          25 :                 memcpy(keyData.data(), key.data(), key.size());
     543             :         }
     544             : 
     545        1025 :         for (auto &it : keyData) {
     546        1000 :                 it ^= HMAC_I_PAD;
     547             :         }
     548             : 
     549          25 :         shaCtx.init().update(keyData).update(data).final(ret.data());
     550             : 
     551        1025 :         for (auto &it : keyData) {
     552        1000 :                 it ^= HMAC_I_PAD ^ HMAC_O_PAD;
     553             :         }
     554             : 
     555          25 :         shaCtx.init().update(keyData).update(ret).final(ret.data());
     556          50 :         return ret;
     557             : }
     558             : 
     559         125 : Sha1::Sha1() { sha1::sha_init(ctx); }
     560         100 : Sha1 & Sha1::init() { sha1::sha_init(ctx); return *this; }
     561             : 
     562         250 : Sha1 & Sha1::update(const uint8_t *ptr, size_t len) {
     563         250 :         if (len > 0) {
     564         250 :                 sha1::sha_process(ctx, ptr, (uint32_t)len);
     565             :         }
     566         250 :         return *this;
     567             : }
     568             : 
     569         250 : Sha1 & Sha1::update(const CoderSource &source) {
     570         250 :         return update(source.data(), source.size());
     571             : }
     572             : 
     573          75 : Sha1::Buf Sha1::final() {
     574             :         Sha1::Buf ret;
     575          75 :         sha1::sha_done(ctx, ret.data());
     576          75 :         return ret;
     577             : }
     578          75 : void Sha1::final(uint8_t *buf) {
     579          75 :         sha1::sha_done(ctx, buf);
     580          75 : }
     581             : 
     582         700 : Sha512::Buf Sha512::make(const CoderSource &source, const StringView &salt) {
     583         700 :         return Sha512().update(salt.empty()?StringView(SP_SECURE_KEY):salt).update(source).final();
     584             : }
     585             : 
     586         225 : Sha512::Buf Sha512::hmac(const CoderSource &data, const CoderSource &key) {
     587             :         Buf ret;
     588         225 :         std::array<uint8_t, Length * 2> keyData = { 0 };
     589             : 
     590         225 :         Sha512 shaCtx;
     591         225 :     if (key.size() > Length * 2) {
     592         125 :         shaCtx.update(key).final(keyData.data());
     593             :     } else {
     594         100 :         memcpy(keyData.data(), key.data(), key.size());
     595             :     }
     596             : 
     597       29025 :     for (auto &it : keyData) {
     598       28800 :         it ^= HMAC_I_PAD;
     599             :     }
     600             : 
     601         225 :     shaCtx.init().update(keyData).update(data).final(ret.data());
     602             : 
     603       29025 :     for (auto &it : keyData) {
     604       28800 :         it ^= HMAC_I_PAD ^ HMAC_O_PAD;
     605             :     }
     606             : 
     607         225 :     shaCtx.init().update(keyData).update(ret).final(ret.data());
     608         450 :     return ret;
     609             : }
     610             : 
     611        1900 : Sha512::Sha512() { sha512::sha_init(ctx); }
     612         450 : Sha512 & Sha512::init() { sha512::sha_init(ctx); return *this; }
     613             : 
     614        4775 : Sha512 & Sha512::update(const uint8_t *ptr, size_t len) {
     615        4775 :         if (len > 0) {
     616        4775 :                 sha512::sha_process(ctx, ptr, (uint32_t)len);
     617             :         }
     618        4775 :         return *this;
     619             : }
     620             : 
     621        4125 : Sha512 & Sha512::update(const CoderSource &source) {
     622        4125 :         return update(source.data(), source.size());
     623             : }
     624             : 
     625        1025 : Sha512::Buf Sha512::final() {
     626             :         Sha512::Buf ret;
     627        1025 :         sha512::sha_done(ctx, ret.data());
     628        1025 :         return ret;
     629             : }
     630        1225 : void Sha512::final(uint8_t *buf) {
     631        1225 :         sha512::sha_done(ctx, buf);
     632        1225 : }
     633             : 
     634             : 
     635          25 : Sha256::Buf Sha256::make(const CoderSource &source, const StringView &salt) {
     636          25 :         return Sha256().update(salt.empty()?StringView(SP_SECURE_KEY):salt).update(source).final();
     637             : }
     638             : 
     639         225 : Sha256::Buf Sha256::hmac(const CoderSource &data, const CoderSource &key) {
     640             :         Buf ret;
     641         225 :         std::array<uint8_t, Length * 2> keyData = { 0 };
     642         225 :         memset(keyData.data(), 0, keyData.size());
     643             : 
     644         225 :         Sha256 shaCtx;
     645         225 :     if (key.size() > Length * 2) {
     646         125 :         shaCtx.init().update(key).final(keyData.data());
     647             :     } else {
     648         100 :         memcpy(keyData.data(), key.data(), key.size());
     649             :     }
     650             : 
     651       14625 :     for (auto &it : keyData) {
     652       14400 :         it ^= HMAC_I_PAD;
     653             :     }
     654             : 
     655         225 :     shaCtx.init().update(keyData).update(data).final(ret.data());
     656             : 
     657       14625 :     for (auto &it : keyData) {
     658       14400 :         it ^= HMAC_I_PAD ^ HMAC_O_PAD;
     659             :     }
     660             : 
     661         225 :     shaCtx.init().update(keyData).update(ret).final(ret.data());
     662         450 :     return ret;
     663             : }
     664             : 
     665         525 : Sha256::Sha256() { sha256::sha_init(ctx); }
     666         575 : Sha256 & Sha256::init() { sha256::sha_init(ctx); return *this; }
     667             : 
     668        1500 : Sha256 & Sha256::update(const uint8_t *ptr, size_t len) {
     669        1500 :         if (len) {
     670        1500 :                 sha256::sha_process(ctx, ptr, (uint32_t)len);
     671             :         }
     672        1500 :         return *this;
     673             : }
     674             : 
     675        1500 : Sha256 & Sha256::update(const CoderSource &source) {
     676        1500 :         return update(source.data(), source.size());
     677             : }
     678             : 
     679         300 : Sha256::Buf Sha256::final() {
     680             :         Sha256::Buf ret;
     681         300 :         sha256::sha_done(ctx, ret.data());
     682         300 :         return ret;
     683             : }
     684         575 : void Sha256::final(uint8_t *buf) {
     685         575 :         sha256::sha_done(ctx, buf);
     686         575 : }
     687             : 
     688             : }

Generated by: LCOV version 1.14