1 // SPDX-License-Identifier: BSD-2-Clause 2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis 3 * 4 * LibTomCrypt is a library that provides various cryptographic 5 * algorithms in a highly modular and flexible manner. 6 * 7 * The library is free for all purposes without any express 8 * guarantee it works. 9 */ 10 #include "tomcrypt_private.h" 11 12 /** 13 @file sha1.c 14 LTC_SHA1 code by Tom St Denis 15 */ 16 17 18 #ifdef LTC_SHA1 19 20 const struct ltc_hash_descriptor sha1_desc = 21 { 22 "sha1", 23 2, 24 20, 25 64, 26 27 /* OID */ 28 { 1, 3, 14, 3, 2, 26, }, 29 6, 30 31 &sha1_init, 32 &sha1_process, 33 &sha1_done, 34 &sha1_test, 35 NULL 36 }; 37 38 #define F0(x,y,z) (z ^ (x & (y ^ z))) 39 #define F1(x,y,z) (x ^ y ^ z) 40 #define F2(x,y,z) ((x & y) | (z & (x | y))) 41 #define F3(x,y,z) (x ^ y ^ z) 42 43 #ifdef LTC_CLEAN_STACK 44 static int _sha1_compress(hash_state *md, const unsigned char *buf) 45 #else 46 static int sha1_compress(hash_state *md, const unsigned char *buf) 47 #endif 48 { 49 ulong32 a,b,c,d,e,W[80],i; 50 #ifdef LTC_SMALL_CODE 51 ulong32 t; 52 #endif 53 54 /* copy the state into 512-bits into W[0..15] */ 55 for (i = 0; i < 16; i++) { 56 LOAD32H(W[i], buf + (4*i)); 57 } 58 59 /* copy state */ 60 a = md->sha1.state[0]; 61 b = md->sha1.state[1]; 62 c = md->sha1.state[2]; 63 d = md->sha1.state[3]; 64 e = md->sha1.state[4]; 65 66 /* expand it */ 67 for (i = 16; i < 80; i++) { 68 W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); 69 } 70 71 /* compress */ 72 /* round one */ 73 #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); 74 #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); 75 #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); 76 #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); 77 78 #ifdef LTC_SMALL_CODE 79 80 for (i = 0; i < 20; ) { 81 FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; 82 } 83 84 for (; i < 40; ) { 85 FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; 86 } 87 88 for (; i < 60; ) { 89 FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; 90 } 91 92 for (; i < 80; ) { 93 FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; 94 } 95 96 #else 97 98 for (i = 0; i < 20; ) { 99 FF0(a,b,c,d,e,i++); 100 FF0(e,a,b,c,d,i++); 101 FF0(d,e,a,b,c,i++); 102 FF0(c,d,e,a,b,i++); 103 FF0(b,c,d,e,a,i++); 104 } 105 106 /* round two */ 107 for (; i < 40; ) { 108 FF1(a,b,c,d,e,i++); 109 FF1(e,a,b,c,d,i++); 110 FF1(d,e,a,b,c,i++); 111 FF1(c,d,e,a,b,i++); 112 FF1(b,c,d,e,a,i++); 113 } 114 115 /* round three */ 116 for (; i < 60; ) { 117 FF2(a,b,c,d,e,i++); 118 FF2(e,a,b,c,d,i++); 119 FF2(d,e,a,b,c,i++); 120 FF2(c,d,e,a,b,i++); 121 FF2(b,c,d,e,a,i++); 122 } 123 124 /* round four */ 125 for (; i < 80; ) { 126 FF3(a,b,c,d,e,i++); 127 FF3(e,a,b,c,d,i++); 128 FF3(d,e,a,b,c,i++); 129 FF3(c,d,e,a,b,i++); 130 FF3(b,c,d,e,a,i++); 131 } 132 #endif 133 134 #undef FF0 135 #undef FF1 136 #undef FF2 137 #undef FF3 138 139 /* store */ 140 md->sha1.state[0] = md->sha1.state[0] + a; 141 md->sha1.state[1] = md->sha1.state[1] + b; 142 md->sha1.state[2] = md->sha1.state[2] + c; 143 md->sha1.state[3] = md->sha1.state[3] + d; 144 md->sha1.state[4] = md->sha1.state[4] + e; 145 146 return CRYPT_OK; 147 } 148 149 #ifdef LTC_CLEAN_STACK 150 static int sha1_compress(hash_state *md, const unsigned char *buf) 151 { 152 int err; 153 err = _sha1_compress(md, buf); 154 burn_stack(sizeof(ulong32) * 87); 155 return err; 156 } 157 #endif 158 159 /** 160 Initialize the hash state 161 @param md The hash state you wish to initialize 162 @return CRYPT_OK if successful 163 */ 164 int sha1_init(hash_state * md) 165 { 166 LTC_ARGCHK(md != NULL); 167 md->sha1.state[0] = 0x67452301UL; 168 md->sha1.state[1] = 0xefcdab89UL; 169 md->sha1.state[2] = 0x98badcfeUL; 170 md->sha1.state[3] = 0x10325476UL; 171 md->sha1.state[4] = 0xc3d2e1f0UL; 172 md->sha1.curlen = 0; 173 md->sha1.length = 0; 174 return CRYPT_OK; 175 } 176 177 /** 178 Process a block of memory though the hash 179 @param md The hash state 180 @param in The data to hash 181 @param inlen The length of the data (octets) 182 @return CRYPT_OK if successful 183 */ 184 HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) 185 186 /** 187 Terminate the hash to get the digest 188 @param md The hash state 189 @param out [out] The destination of the hash (20 bytes) 190 @return CRYPT_OK if successful 191 */ 192 int sha1_done(hash_state * md, unsigned char *out) 193 { 194 int i; 195 196 LTC_ARGCHK(md != NULL); 197 LTC_ARGCHK(out != NULL); 198 199 if (md->sha1.curlen >= sizeof(md->sha1.buf)) { 200 return CRYPT_INVALID_ARG; 201 } 202 203 /* increase the length of the message */ 204 md->sha1.length += md->sha1.curlen * 8; 205 206 /* append the '1' bit */ 207 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; 208 209 /* if the length is currently above 56 bytes we append zeros 210 * then compress. Then we can fall back to padding zeros and length 211 * encoding like normal. 212 */ 213 if (md->sha1.curlen > 56) { 214 while (md->sha1.curlen < 64) { 215 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; 216 } 217 sha1_compress(md, md->sha1.buf); 218 md->sha1.curlen = 0; 219 } 220 221 /* pad upto 56 bytes of zeroes */ 222 while (md->sha1.curlen < 56) { 223 md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; 224 } 225 226 /* store length */ 227 STORE64H(md->sha1.length, md->sha1.buf+56); 228 sha1_compress(md, md->sha1.buf); 229 230 /* copy output */ 231 for (i = 0; i < 5; i++) { 232 STORE32H(md->sha1.state[i], out+(4*i)); 233 } 234 #ifdef LTC_CLEAN_STACK 235 zeromem(md, sizeof(hash_state)); 236 #endif 237 return CRYPT_OK; 238 } 239 240 /** 241 Self-test the hash 242 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled 243 */ 244 int sha1_test(void) 245 { 246 #ifndef LTC_TEST 247 return CRYPT_NOP; 248 #else 249 static const struct { 250 const char *msg; 251 unsigned char hash[20]; 252 } tests[] = { 253 { "abc", 254 { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 255 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 256 0x9c, 0xd0, 0xd8, 0x9d } 257 }, 258 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 259 { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 260 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 261 0xE5, 0x46, 0x70, 0xF1 } 262 } 263 }; 264 265 int i; 266 unsigned char tmp[20]; 267 hash_state md; 268 269 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { 270 sha1_init(&md); 271 sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); 272 sha1_done(&md, tmp); 273 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) { 274 return CRYPT_FAIL_TESTVECTOR; 275 } 276 } 277 return CRYPT_OK; 278 #endif 279 } 280 281 #endif 282 283 284 285 /* ref: $Format:%D$ */ 286 /* git commit: $Format:%H$ */ 287 /* commit time: $Format:%ai$ */ 288