1*eabc0478Schristos /* $NetBSD: sha1.c,v 1.2 2024/08/18 20:47:14 christos Exp $ */ 2897be3a4Schristos 3897be3a4Schristos /* 4897be3a4Schristos * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") 5897be3a4Schristos * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. 6897be3a4Schristos * 7897be3a4Schristos * Permission to use, copy, modify, and/or distribute this software for any 8897be3a4Schristos * purpose with or without fee is hereby granted, provided that the above 9897be3a4Schristos * copyright notice and this permission notice appear in all copies. 10897be3a4Schristos * 11897be3a4Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12897be3a4Schristos * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13897be3a4Schristos * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14897be3a4Schristos * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15897be3a4Schristos * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16897be3a4Schristos * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17897be3a4Schristos * PERFORMANCE OF THIS SOFTWARE. 18897be3a4Schristos */ 19897be3a4Schristos 20897be3a4Schristos /* Id */ 21897be3a4Schristos 22897be3a4Schristos /* NetBSD: sha1.c,v 1.5 2000/01/22 22:19:14 mycroft Exp */ 23897be3a4Schristos /* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */ 24897be3a4Schristos 25897be3a4Schristos /*! \file 26897be3a4Schristos * SHA-1 in C 27897be3a4Schristos * \author By Steve Reid <steve@edmweb.com> 28897be3a4Schristos * 100% Public Domain 29897be3a4Schristos * \verbatim 30897be3a4Schristos * Test Vectors (from FIPS PUB 180-1) 31897be3a4Schristos * "abc" 32897be3a4Schristos * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 33897be3a4Schristos * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 34897be3a4Schristos * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 35897be3a4Schristos * A million repetitions of "a" 36897be3a4Schristos * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 37897be3a4Schristos * \endverbatim 38897be3a4Schristos */ 39897be3a4Schristos 40897be3a4Schristos #include "config.h" 41897be3a4Schristos 42897be3a4Schristos #include <isc/assertions.h> 43897be3a4Schristos #include <isc/platform.h> 44897be3a4Schristos #include <isc/sha1.h> 45897be3a4Schristos #include <isc/string.h> 46897be3a4Schristos #include <isc/types.h> 47897be3a4Schristos #include <isc/util.h> 48897be3a4Schristos 49897be3a4Schristos #ifdef ISC_PLATFORM_OPENSSLHASH 50897be3a4Schristos 51897be3a4Schristos void 52897be3a4Schristos isc_sha1_init(isc_sha1_t *context) 53897be3a4Schristos { 54897be3a4Schristos INSIST(context != NULL); 55897be3a4Schristos 56897be3a4Schristos EVP_DigestInit(context, EVP_sha1()); 57897be3a4Schristos } 58897be3a4Schristos 59897be3a4Schristos void 60897be3a4Schristos isc_sha1_invalidate(isc_sha1_t *context) { 61897be3a4Schristos EVP_MD_CTX_cleanup(context); 62897be3a4Schristos } 63897be3a4Schristos 64897be3a4Schristos void 65897be3a4Schristos isc_sha1_update(isc_sha1_t *context, const unsigned char *data, 66897be3a4Schristos unsigned int len) 67897be3a4Schristos { 68897be3a4Schristos INSIST(context != 0); 69897be3a4Schristos INSIST(data != 0); 70897be3a4Schristos 71897be3a4Schristos EVP_DigestUpdate(context, (const void *) data, (size_t) len); 72897be3a4Schristos } 73897be3a4Schristos 74897be3a4Schristos void 75897be3a4Schristos isc_sha1_final(isc_sha1_t *context, unsigned char *digest) { 76897be3a4Schristos INSIST(digest != 0); 77897be3a4Schristos INSIST(context != 0); 78897be3a4Schristos 79897be3a4Schristos EVP_DigestFinal(context, digest, NULL); 80897be3a4Schristos } 81897be3a4Schristos 82897be3a4Schristos #else 83897be3a4Schristos 84897be3a4Schristos #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 85897be3a4Schristos 86897be3a4Schristos /*@{*/ 87897be3a4Schristos /*! 88897be3a4Schristos * blk0() and blk() perform the initial expand. 89897be3a4Schristos * I got the idea of expanding during the round function from SSLeay 90897be3a4Schristos */ 91897be3a4Schristos #if !defined(WORDS_BIGENDIAN) 92897be3a4Schristos # define blk0(i) \ 93897be3a4Schristos (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) \ 94897be3a4Schristos | (rol(block->l[i], 8) & 0x00FF00FF)) 95897be3a4Schristos #else 96897be3a4Schristos # define blk0(i) block->l[i] 97897be3a4Schristos #endif 98897be3a4Schristos #define blk(i) \ 99897be3a4Schristos (block->l[i & 15] = rol(block->l[(i + 13) & 15] \ 100897be3a4Schristos ^ block->l[(i + 8) & 15] \ 101897be3a4Schristos ^ block->l[(i + 2) & 15] \ 102897be3a4Schristos ^ block->l[i & 15], 1)) 103897be3a4Schristos 104897be3a4Schristos /*@}*/ 105897be3a4Schristos /*@{*/ 106897be3a4Schristos /*! 107897be3a4Schristos * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 108897be3a4Schristos */ 109897be3a4Schristos #define R0(v,w,x,y,z,i) \ 110897be3a4Schristos z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \ 111897be3a4Schristos w = rol(w, 30); 112897be3a4Schristos #define R1(v,w,x,y,z,i) \ 113897be3a4Schristos z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \ 114897be3a4Schristos w = rol(w, 30); 115897be3a4Schristos #define R2(v,w,x,y,z,i) \ 116897be3a4Schristos z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \ 117897be3a4Schristos w = rol(w, 30); 118897be3a4Schristos #define R3(v,w,x,y,z,i) \ 119897be3a4Schristos z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \ 120897be3a4Schristos w = rol(w, 30); 121897be3a4Schristos #define R4(v,w,x,y,z,i) \ 122897be3a4Schristos z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \ 123897be3a4Schristos w = rol(w, 30); 124897be3a4Schristos 125897be3a4Schristos /*@}*/ 126897be3a4Schristos 127897be3a4Schristos typedef union { 128897be3a4Schristos unsigned char c[64]; 129897be3a4Schristos unsigned int l[16]; 130897be3a4Schristos } CHAR64LONG16; 131897be3a4Schristos 132897be3a4Schristos #ifdef __sparc_v9__ 133897be3a4Schristos static void do_R01(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, 134897be3a4Schristos isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *); 135897be3a4Schristos static void do_R2(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, 136897be3a4Schristos isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *); 137897be3a4Schristos static void do_R3(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, 138897be3a4Schristos isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *); 139897be3a4Schristos static void do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, 140897be3a4Schristos isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *); 141897be3a4Schristos 142897be3a4Schristos #define nR0(v,w,x,y,z,i) R0(*v,*w,*x,*y,*z,i) 143897be3a4Schristos #define nR1(v,w,x,y,z,i) R1(*v,*w,*x,*y,*z,i) 144897be3a4Schristos #define nR2(v,w,x,y,z,i) R2(*v,*w,*x,*y,*z,i) 145897be3a4Schristos #define nR3(v,w,x,y,z,i) R3(*v,*w,*x,*y,*z,i) 146897be3a4Schristos #define nR4(v,w,x,y,z,i) R4(*v,*w,*x,*y,*z,i) 147897be3a4Schristos 148897be3a4Schristos static void 149897be3a4Schristos do_R01(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, 150897be3a4Schristos isc_uint32_t *e, CHAR64LONG16 *block) 151897be3a4Schristos { 152897be3a4Schristos nR0(a,b,c,d,e, 0); nR0(e,a,b,c,d, 1); nR0(d,e,a,b,c, 2); 153897be3a4Schristos nR0(c,d,e,a,b, 3); nR0(b,c,d,e,a, 4); nR0(a,b,c,d,e, 5); 154897be3a4Schristos nR0(e,a,b,c,d, 6); nR0(d,e,a,b,c, 7); nR0(c,d,e,a,b, 8); 155897be3a4Schristos nR0(b,c,d,e,a, 9); nR0(a,b,c,d,e,10); nR0(e,a,b,c,d,11); 156897be3a4Schristos nR0(d,e,a,b,c,12); nR0(c,d,e,a,b,13); nR0(b,c,d,e,a,14); 157897be3a4Schristos nR0(a,b,c,d,e,15); nR1(e,a,b,c,d,16); nR1(d,e,a,b,c,17); 158897be3a4Schristos nR1(c,d,e,a,b,18); nR1(b,c,d,e,a,19); 159897be3a4Schristos } 160897be3a4Schristos 161897be3a4Schristos static void 162897be3a4Schristos do_R2(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, 163897be3a4Schristos isc_uint32_t *e, CHAR64LONG16 *block) 164897be3a4Schristos { 165897be3a4Schristos nR2(a,b,c,d,e,20); nR2(e,a,b,c,d,21); nR2(d,e,a,b,c,22); 166897be3a4Schristos nR2(c,d,e,a,b,23); nR2(b,c,d,e,a,24); nR2(a,b,c,d,e,25); 167897be3a4Schristos nR2(e,a,b,c,d,26); nR2(d,e,a,b,c,27); nR2(c,d,e,a,b,28); 168897be3a4Schristos nR2(b,c,d,e,a,29); nR2(a,b,c,d,e,30); nR2(e,a,b,c,d,31); 169897be3a4Schristos nR2(d,e,a,b,c,32); nR2(c,d,e,a,b,33); nR2(b,c,d,e,a,34); 170897be3a4Schristos nR2(a,b,c,d,e,35); nR2(e,a,b,c,d,36); nR2(d,e,a,b,c,37); 171897be3a4Schristos nR2(c,d,e,a,b,38); nR2(b,c,d,e,a,39); 172897be3a4Schristos } 173897be3a4Schristos 174897be3a4Schristos static void 175897be3a4Schristos do_R3(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, 176897be3a4Schristos isc_uint32_t *e, CHAR64LONG16 *block) 177897be3a4Schristos { 178897be3a4Schristos nR3(a,b,c,d,e,40); nR3(e,a,b,c,d,41); nR3(d,e,a,b,c,42); 179897be3a4Schristos nR3(c,d,e,a,b,43); nR3(b,c,d,e,a,44); nR3(a,b,c,d,e,45); 180897be3a4Schristos nR3(e,a,b,c,d,46); nR3(d,e,a,b,c,47); nR3(c,d,e,a,b,48); 181897be3a4Schristos nR3(b,c,d,e,a,49); nR3(a,b,c,d,e,50); nR3(e,a,b,c,d,51); 182897be3a4Schristos nR3(d,e,a,b,c,52); nR3(c,d,e,a,b,53); nR3(b,c,d,e,a,54); 183897be3a4Schristos nR3(a,b,c,d,e,55); nR3(e,a,b,c,d,56); nR3(d,e,a,b,c,57); 184897be3a4Schristos nR3(c,d,e,a,b,58); nR3(b,c,d,e,a,59); 185897be3a4Schristos } 186897be3a4Schristos 187897be3a4Schristos static void 188897be3a4Schristos do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d, 189897be3a4Schristos isc_uint32_t *e, CHAR64LONG16 *block) 190897be3a4Schristos { 191897be3a4Schristos nR4(a,b,c,d,e,60); nR4(e,a,b,c,d,61); nR4(d,e,a,b,c,62); 192897be3a4Schristos nR4(c,d,e,a,b,63); nR4(b,c,d,e,a,64); nR4(a,b,c,d,e,65); 193897be3a4Schristos nR4(e,a,b,c,d,66); nR4(d,e,a,b,c,67); nR4(c,d,e,a,b,68); 194897be3a4Schristos nR4(b,c,d,e,a,69); nR4(a,b,c,d,e,70); nR4(e,a,b,c,d,71); 195897be3a4Schristos nR4(d,e,a,b,c,72); nR4(c,d,e,a,b,73); nR4(b,c,d,e,a,74); 196897be3a4Schristos nR4(a,b,c,d,e,75); nR4(e,a,b,c,d,76); nR4(d,e,a,b,c,77); 197897be3a4Schristos nR4(c,d,e,a,b,78); nR4(b,c,d,e,a,79); 198897be3a4Schristos } 199897be3a4Schristos #endif 200897be3a4Schristos 201897be3a4Schristos /*! 202897be3a4Schristos * Hash a single 512-bit block. This is the core of the algorithm. 203897be3a4Schristos */ 204897be3a4Schristos static void 205897be3a4Schristos transform(isc_uint32_t state[5], const unsigned char buffer[64]) { 206897be3a4Schristos isc_uint32_t a, b, c, d, e; 207897be3a4Schristos CHAR64LONG16 *block; 208897be3a4Schristos CHAR64LONG16 workspace; 209897be3a4Schristos 210897be3a4Schristos INSIST(buffer != NULL); 211897be3a4Schristos INSIST(state != NULL); 212897be3a4Schristos 213897be3a4Schristos block = &workspace; 214897be3a4Schristos (void)memcpy(block, buffer, 64); 215897be3a4Schristos 216897be3a4Schristos /* Copy context->state[] to working vars */ 217897be3a4Schristos a = state[0]; 218897be3a4Schristos b = state[1]; 219897be3a4Schristos c = state[2]; 220897be3a4Schristos d = state[3]; 221897be3a4Schristos e = state[4]; 222897be3a4Schristos 223897be3a4Schristos #ifdef __sparc_v9__ 224897be3a4Schristos do_R01(&a, &b, &c, &d, &e, block); 225897be3a4Schristos do_R2(&a, &b, &c, &d, &e, block); 226897be3a4Schristos do_R3(&a, &b, &c, &d, &e, block); 227897be3a4Schristos do_R4(&a, &b, &c, &d, &e, block); 228897be3a4Schristos #else 229897be3a4Schristos /* 4 rounds of 20 operations each. Loop unrolled. */ 230897be3a4Schristos R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 231897be3a4Schristos R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 232897be3a4Schristos R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 233897be3a4Schristos R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 234897be3a4Schristos R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 235897be3a4Schristos R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 236897be3a4Schristos R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 237897be3a4Schristos R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 238897be3a4Schristos R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 239897be3a4Schristos R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 240897be3a4Schristos R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 241897be3a4Schristos R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 242897be3a4Schristos R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 243897be3a4Schristos R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 244897be3a4Schristos R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 245897be3a4Schristos R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 246897be3a4Schristos R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 247897be3a4Schristos R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 248897be3a4Schristos R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 249897be3a4Schristos R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 250897be3a4Schristos #endif 251897be3a4Schristos 252897be3a4Schristos /* Add the working vars back into context.state[] */ 253897be3a4Schristos state[0] += a; 254897be3a4Schristos state[1] += b; 255897be3a4Schristos state[2] += c; 256897be3a4Schristos state[3] += d; 257897be3a4Schristos state[4] += e; 258897be3a4Schristos 259897be3a4Schristos /* Wipe variables */ 260897be3a4Schristos a = b = c = d = e = 0; 261897be3a4Schristos /* Avoid compiler warnings */ 262897be3a4Schristos POST(a); POST(b); POST(c); POST(d); POST(e); 263897be3a4Schristos } 264897be3a4Schristos 265897be3a4Schristos 266897be3a4Schristos /*! 267897be3a4Schristos * isc_sha1_init - Initialize new context 268897be3a4Schristos */ 269897be3a4Schristos void 270897be3a4Schristos isc_sha1_init(isc_sha1_t *context) 271897be3a4Schristos { 272897be3a4Schristos INSIST(context != NULL); 273897be3a4Schristos 274897be3a4Schristos /* SHA1 initialization constants */ 275897be3a4Schristos context->state[0] = 0x67452301; 276897be3a4Schristos context->state[1] = 0xEFCDAB89; 277897be3a4Schristos context->state[2] = 0x98BADCFE; 278897be3a4Schristos context->state[3] = 0x10325476; 279897be3a4Schristos context->state[4] = 0xC3D2E1F0; 280897be3a4Schristos context->count[0] = 0; 281897be3a4Schristos context->count[1] = 0; 282897be3a4Schristos } 283897be3a4Schristos 284897be3a4Schristos void 285897be3a4Schristos isc_sha1_invalidate(isc_sha1_t *context) { 286897be3a4Schristos memset(context, 0, sizeof(isc_sha1_t)); 287897be3a4Schristos } 288897be3a4Schristos 289897be3a4Schristos /*! 290897be3a4Schristos * Run your data through this. 291897be3a4Schristos */ 292897be3a4Schristos void 293897be3a4Schristos isc_sha1_update(isc_sha1_t *context, const unsigned char *data, 294897be3a4Schristos unsigned int len) 295897be3a4Schristos { 296897be3a4Schristos unsigned int i, j; 297897be3a4Schristos 298897be3a4Schristos INSIST(context != 0); 299897be3a4Schristos INSIST(data != 0); 300897be3a4Schristos 301897be3a4Schristos j = context->count[0]; 302897be3a4Schristos if ((context->count[0] += len << 3) < j) 303897be3a4Schristos context->count[1] += (len >> 29) + 1; 304897be3a4Schristos j = (j >> 3) & 63; 305897be3a4Schristos if ((j + len) > 63) { 306897be3a4Schristos (void)memcpy(&context->buffer[j], data, (i = 64 - j)); 307897be3a4Schristos transform(context->state, context->buffer); 308897be3a4Schristos for (; i + 63 < len; i += 64) 309897be3a4Schristos transform(context->state, &data[i]); 310897be3a4Schristos j = 0; 311897be3a4Schristos } else { 312897be3a4Schristos i = 0; 313897be3a4Schristos } 314897be3a4Schristos 315897be3a4Schristos (void)memcpy(&context->buffer[j], &data[i], len - i); 316897be3a4Schristos } 317897be3a4Schristos 318897be3a4Schristos 319897be3a4Schristos /*! 320897be3a4Schristos * Add padding and return the message digest. 321897be3a4Schristos */ 322897be3a4Schristos 323897be3a4Schristos static const unsigned char final_200 = 128; 324897be3a4Schristos static const unsigned char final_0 = 0; 325897be3a4Schristos 326897be3a4Schristos void 327897be3a4Schristos isc_sha1_final(isc_sha1_t *context, unsigned char *digest) { 328897be3a4Schristos unsigned int i; 329897be3a4Schristos unsigned char finalcount[8]; 330897be3a4Schristos 331897be3a4Schristos INSIST(digest != 0); 332897be3a4Schristos INSIST(context != 0); 333897be3a4Schristos 334897be3a4Schristos for (i = 0; i < 8; i++) { 335897be3a4Schristos /* Endian independent */ 336897be3a4Schristos finalcount[i] = (unsigned char) 337897be3a4Schristos ((context->count[(i >= 4 ? 0 : 1)] 338897be3a4Schristos >> ((3 - (i & 3)) * 8)) & 255); 339897be3a4Schristos } 340897be3a4Schristos 341897be3a4Schristos isc_sha1_update(context, &final_200, 1); 342897be3a4Schristos while ((context->count[0] & 504) != 448) 343897be3a4Schristos isc_sha1_update(context, &final_0, 1); 344897be3a4Schristos /* The next Update should cause a transform() */ 345897be3a4Schristos isc_sha1_update(context, finalcount, 8); 346897be3a4Schristos 347897be3a4Schristos if (digest) { 348897be3a4Schristos for (i = 0; i < 20; i++) 349897be3a4Schristos digest[i] = (unsigned char) 350897be3a4Schristos ((context->state[i >> 2] 351897be3a4Schristos >> ((3 - (i & 3)) * 8)) & 255); 352897be3a4Schristos } 353897be3a4Schristos 354897be3a4Schristos memset(context, 0, sizeof(isc_sha1_t)); 355897be3a4Schristos } 356897be3a4Schristos #endif 357