1 /*- 2 * Copyright (c) 2009 The Go Authors. All rights reserved. 3 * Copyright (c) 2024 Robert Clausecker <fuz@freebsd.org> 4 * 5 * Adapted from Go's crypto/sha1/sha1.go. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following disclaimer 15 * in the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Google Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived from 19 * this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <assert.h> 35 #include <sha.h> 36 #include <stdint.h> 37 #include <string.h> 38 #include <strings.h> 39 #include <sys/endian.h> 40 41 #ifdef SHA1_ASM 42 extern void sha1_block(SHA1_CTX *, const void *, size_t); 43 #else 44 static void sha1_block(SHA1_CTX *, const void *, size_t); 45 #endif 46 47 #define INIT0 0x67452301 48 #define INIT1 0xEFCDAB89 49 #define INIT2 0x98BADCFE 50 #define INIT3 0x10325476 51 #define INIT4 0xC3D2E1F0 52 53 #define K0 0x5A827999 54 #define K1 0x6ED9EBA1 55 #define K2 0x8F1BBCDC 56 #define K3 0xCA62C1D6 57 58 void 59 SHA1_Init(SHA1_CTX *c) 60 { 61 c->h0 = INIT0; 62 c->h1 = INIT1; 63 c->h2 = INIT2; 64 c->h3 = INIT3; 65 c->h4 = INIT4; 66 c->Nl = 0; 67 c->Nh = 0; 68 c->num = 0; 69 } 70 71 void 72 SHA1_Update(SHA1_CTX *c, const void *data, size_t len) 73 { 74 uint64_t nn; 75 const char *p = data; 76 77 nn = (uint64_t)c->Nl | (uint64_t)c->Nh << 32; 78 nn += len; 79 c->Nl = (uint32_t)nn; 80 c->Nh = (uint32_t)(nn >> 32); 81 82 if (c->num > 0) { 83 size_t n = SHA_CBLOCK - c->num; 84 85 if (n > len) 86 n = len; 87 88 memcpy((char *)c->data + c->num, p, n); 89 c->num += n; 90 if (c->num == SHA_CBLOCK) { 91 sha1_block(c, (void *)c->data, SHA_CBLOCK); 92 c->num = 0; 93 } 94 95 p += n; 96 len -= n; 97 } 98 99 if (len >= SHA_CBLOCK) { 100 size_t n = len & ~(size_t)(SHA_CBLOCK - 1); 101 102 sha1_block(c, p, n); 103 p += n; 104 len -= n; 105 } 106 107 if (len > 0) { 108 memcpy(c->data, p, len); 109 c->num = len; 110 } 111 } 112 113 void 114 SHA1_Final(unsigned char *md, SHA1_CTX *c) 115 { 116 uint64_t len; 117 size_t t; 118 unsigned char tmp[SHA_CBLOCK + sizeof(uint64_t)] = {0x80, 0}; 119 120 len = (uint64_t)c->Nl | (uint64_t)c->Nh << 32; 121 t = 64 + 56 - c->Nl % 64; 122 if (t > 64) 123 t -= 64; 124 125 /* length in bits */ 126 len <<= 3; 127 be64enc(tmp + t, len); 128 SHA1_Update(c, tmp, t + 8); 129 assert(c->num == 0); 130 131 be32enc(md + 0, c->h0); 132 be32enc(md + 4, c->h1); 133 be32enc(md + 8, c->h2); 134 be32enc(md + 12, c->h3); 135 be32enc(md + 16, c->h4); 136 137 explicit_bzero(c, sizeof(*c)); 138 } 139 140 #ifndef SHA1_ASM 141 static void 142 /* invariant: len is a multiple of SHA_CBLOCK */ 143 sha1_block(SHA1_CTX *c, const void *data, size_t len) 144 { 145 uint32_t w[16]; 146 uint32_t h0 = c->h0, h1 = c->h1, h2 = c->h2, h3 = c->h3, h4 = c->h4; 147 const char *p = data; 148 149 while (len >= SHA_CBLOCK) { 150 size_t i; 151 uint32_t a = h0, b = h1, c = h2, d = h3, e = h4; 152 uint32_t f, t, tmp; 153 154 # pragma unroll 155 for (i = 0; i < 16; i++) 156 w[i] = be32dec(p + 4*i); 157 158 # pragma unroll 159 for (i = 0; i < 16; i++) { 160 f = b & c | ~b & d; 161 t = (a << 5 | a >> 32 - 5) + f + e + w[i & 0xf] + K0; 162 e = d; 163 d = c; 164 c = b << 30 | b >> 32 - 30; 165 b = a; 166 a = t; 167 } 168 169 # pragma unroll 170 for (; i < 20; i++) { 171 tmp = w[i - 3 & 0xf] ^ w[i - 8 & 0xf] ^ w[i - 14 & 0xf] ^ w[i & 0xf]; 172 w[i & 0xf] = tmp << 1 | tmp >> 32 - 1; 173 174 f = b & c | ~b & d; 175 t = (a << 5 | a >> 32 - 5) + f + e + w[i & 0xf] + K0; 176 e = d; 177 d = c; 178 c = b << 30 | b >> 32 - 30; 179 b = a; 180 a = t; 181 } 182 183 # pragma unroll 184 for (; i < 40; i++) { 185 tmp = w[i - 3 & 0xf] ^ w[i - 8 & 0xf] ^ w[i - 14 & 0xf] ^ w[i & 0xf]; 186 w[i & 0xf] = tmp << 1 | tmp >> 32 - 1; 187 188 f = b ^ c ^ d; 189 t = (a << 5 | a >> 32 - 5) + f + e + w[i & 0xf] + K1; 190 e = d; 191 d = c; 192 c = b << 30 | b >> 32 - 30; 193 b = a; 194 a = t; 195 } 196 197 # pragma unroll 198 for (; i < 60; i++) { 199 tmp = w[i - 3 & 0xf] ^ w[i - 8 & 0xf] ^ w[i - 14 & 0xf] ^ w[i & 0xf]; 200 w[i & 0xf] = tmp << 1 | tmp >> 32 - 1; 201 202 f = (b | c) & d | b & c; 203 t = (a << 5 | a >> 32 - 5) + f + e + w[i & 0xf] + K2; 204 e = d; 205 d = c; 206 c = b << 30 | b >> 32 - 30; 207 b = a; 208 a = t; 209 } 210 211 # pragma unroll 212 for (; i < 80; i++) { 213 tmp = w[i - 3 & 0xf] ^ w[i - 8 & 0xf] ^ w[i - 14 & 0xf] ^ w[i & 0xf]; 214 w[i & 0xf] = tmp << 1 | tmp >> 32 - 1; 215 216 f = b ^ c ^ d; 217 t = (a << 5 | a >> 32 - 5) + f + e + w[i & 0xf] + K3; 218 e = d; 219 d = c; 220 c = b << 30 | b >> 32 - 30; 221 b = a; 222 a = t; 223 } 224 225 h0 += a; 226 h1 += b; 227 h2 += c; 228 h3 += d; 229 h4 += e; 230 231 p += SHA_CBLOCK; 232 len -= SHA_CBLOCK; 233 } 234 235 c->h0 = h0; 236 c->h1 = h1; 237 c->h2 = h2; 238 c->h3 = h3; 239 c->h4 = h4; 240 } 241 #endif 242 243 #ifdef WEAK_REFS 244 /* When building libmd, provide weak references. Note: this is not 245 activated in the context of compiling these sources for internal 246 use in libcrypt. 247 */ 248 #undef SHA_Init 249 __weak_reference(_libmd_SHA_Init, SHA_Init); 250 #undef SHA_Update 251 __weak_reference(_libmd_SHA_Update, SHA_Update); 252 #undef SHA_Final 253 __weak_reference(_libmd_SHA_Final, SHA_Final); 254 #undef SHA1_Init 255 __weak_reference(_libmd_SHA1_Init, SHA1_Init); 256 #undef SHA1_Update 257 __weak_reference(_libmd_SHA1_Update, SHA1_Update); 258 #undef SHA1_Final 259 __weak_reference(_libmd_SHA1_Final, SHA1_Final); 260 #endif 261