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 adler32.c 14 Adler-32 checksum algorithm 15 Written and placed in the public domain by Wei Dai 16 Adapted for libtomcrypt by Steffen Jaeckel 17 */ 18 #ifdef LTC_ADLER32 19 20 static const unsigned long _adler32_base = 65521; 21 22 void adler32_init(adler32_state *ctx) 23 { 24 LTC_ARGCHKVD(ctx != NULL); 25 ctx->s[0] = 1; 26 ctx->s[1] = 0; 27 } 28 29 void adler32_update(adler32_state *ctx, const unsigned char *input, unsigned long length) 30 { 31 unsigned long s1, s2; 32 33 LTC_ARGCHKVD(ctx != NULL); 34 LTC_ARGCHKVD(input != NULL); 35 s1 = ctx->s[0]; 36 s2 = ctx->s[1]; 37 38 if (length % 8 != 0) { 39 do { 40 s1 += *input++; 41 s2 += s1; 42 length--; 43 } while (length % 8 != 0); 44 45 if (s1 >= _adler32_base) { 46 s1 -= _adler32_base; 47 } 48 s2 %= _adler32_base; 49 } 50 51 while (length > 0) { 52 s1 += input[0]; 53 s2 += s1; 54 s1 += input[1]; 55 s2 += s1; 56 s1 += input[2]; 57 s2 += s1; 58 s1 += input[3]; 59 s2 += s1; 60 s1 += input[4]; 61 s2 += s1; 62 s1 += input[5]; 63 s2 += s1; 64 s1 += input[6]; 65 s2 += s1; 66 s1 += input[7]; 67 s2 += s1; 68 69 length -= 8; 70 input += 8; 71 72 if (s1 >= _adler32_base) { 73 s1 -= _adler32_base; 74 } 75 s2 %= _adler32_base; 76 } 77 78 LTC_ARGCHKVD(s1 < _adler32_base); 79 LTC_ARGCHKVD(s2 < _adler32_base); 80 81 ctx->s[0] = (unsigned short)s1; 82 ctx->s[1] = (unsigned short)s2; 83 } 84 85 void adler32_finish(const adler32_state *ctx, void *hash, unsigned long size) 86 { 87 unsigned char* h; 88 89 LTC_ARGCHKVD(ctx != NULL); 90 LTC_ARGCHKVD(hash != NULL); 91 92 h = hash; 93 94 switch (size) { 95 default: 96 h[3] = ctx->s[0] & 0x0ff; 97 /* FALLTHROUGH */ 98 case 3: 99 h[2] = (ctx->s[0] >> 8) & 0x0ff; 100 /* FALLTHROUGH */ 101 case 2: 102 h[1] = ctx->s[1] & 0x0ff; 103 /* FALLTHROUGH */ 104 case 1: 105 h[0] = (ctx->s[1] >> 8) & 0x0ff; 106 /* FALLTHROUGH */ 107 case 0: 108 ; 109 } 110 } 111 112 int adler32_test(void) 113 { 114 #ifndef LTC_TEST 115 return CRYPT_NOP; 116 #else 117 const void* in = "libtomcrypt"; 118 const unsigned char adler32[] = { 0x1b, 0xe8, 0x04, 0xba }; 119 unsigned char out[4]; 120 adler32_state ctx; 121 adler32_init(&ctx); 122 adler32_update(&ctx, in, strlen(in)); 123 adler32_finish(&ctx, out, 4); 124 if (compare_testvector(adler32, 4, out, 4, "adler32", 0)) { 125 return CRYPT_FAIL_TESTVECTOR; 126 } 127 return CRYPT_OK; 128 #endif 129 } 130 #endif 131 132 /* ref: $Format:%D$ */ 133 /* git commit: $Format:%H$ */ 134 /* commit time: $Format:%ai$ */ 135