├── .gitignore ├── .travis.yml ├── Makefile ├── README.rst ├── clib.json ├── sha1.c ├── sha1.h └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | lib 2 | sha1test 3 | *.o 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | compiler: 4 | - clang 5 | - gcc 6 | 7 | script: make test 8 | 9 | sudo: false 10 | 11 | addons: 12 | apt: 13 | packages: 14 | - libcunit 15 | - libcunit1-dev 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET=$(shell $(CC) -dumpmachine) 2 | 3 | CFLAGS=-Wall -Werror 4 | 5 | TESTCFLAGS=-g $(CFLAGS) 6 | TESTLINKER=-lcunit 7 | TESTSOURCES=test.c sha1.c 8 | TESTBINARY=sha1test 9 | 10 | SOURCES=sha1.c 11 | OBJECTS=$(patsubst %.c,objs/$(TARGET)/%.c.o,$(SOURCES)) 12 | 13 | .PHONY: static 14 | .FORCE: test 15 | all: 16 | make test 17 | 18 | lib/$(TARGET): 19 | mkdir -p $@ 20 | 21 | objs/$(TARGET): 22 | mkdir -p $@ 23 | 24 | objs/$(TARGET)/%.c.o: %.c objs/$(TARGET) lib/$(TARGET) 25 | $(CC) $(CFLAGS) -c $< -o $@ 26 | 27 | lib/$(TARGET)/libsha1.a: $(OBJECTS) 28 | $(AR) rcs $@ $^ 29 | 30 | static: lib/$(TARGET)/libsha1.a 31 | @echo "Built $@" 32 | 33 | clean: 34 | rm -rf *.o $(TESTBINARY) 35 | rm -rf lib out 36 | 37 | test: 38 | $(CC) $(TESTCFLAGS) -o $(TESTBINARY) $(TESTSOURCES) $(TESTLINKER) 39 | ./$(TESTBINARY) 40 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | NAME 2 | SHA1Init, SHA1Update, SHA1Final, SHA1Transform 3 | 4 | SYNOPSIS 5 | #include 6 | 7 | #include 8 | 9 | void SHA1Transform( 10 | uint32_t state[5], 11 | const unsigned char buffer[64]); 12 | 13 | void SHA1Init( 14 | SHA1_CTX * context); 15 | 16 | void SHA1Update( 17 | SHA1_CTX * context, 18 | const unsigned char *data, 19 | uint32_t len); 20 | 21 | void SHA1Final( 22 | unsigned char digest[20], 23 | SHA1_CTX * context); 24 | 25 | DESCRIPTION 26 | The SHA1 functions implement the NIST Secure Hash Algorithm (SHA-1), FIPS 27 | PUB 180-1. SHA-1 is used to generate a condensed representation of a 28 | message called a message digest. The algorithm takes a message less than 29 | 2^64 bits as input and produces a 160-bit digest suitable for use as a 30 | digital signature. 31 | 32 | The SHA1Init() function initializes a SHA1_CTX context for use with 33 | SHA1Update(), and SHA1Final(). The SHA1Update() function adds data of 34 | length len to the SHA1_CTX specified by context. SHA1Final() is called 35 | when all data has been added via SHA1Update() and stores a message digest 36 | in the digest parameter. When a null pointer is passed to SHA1Final() as 37 | first argument only the final padding will be applied and the current 38 | context can still be used with SHA1Update(). 39 | 40 | The SHA1Transform() function is used by SHA1Update() to hash 512-bit 41 | blocks and forms the core of the algorithm. Most programs should use the 42 | interface provided by SHA1Init(), SHA1Update() and SHA1Final() instead of 43 | calling SHA1Transform() directly. 44 | 45 | EXAMPLES 46 | The follow code fragment will calculate the digest for the string "abc" 47 | which is ``0xa9993e36476816aba3e25717850c26c9cd0d89d''. 48 | 49 | SHA1_CTX sha; 50 | uint8_t results[20]; 51 | char *buf; 52 | int n; 53 | 54 | buf = "abc"; 55 | n = strlen(buf); 56 | SHA1Init(&sha); 57 | SHA1Update(&sha, (uint8_t *)buf, n); 58 | SHA1Final(results, &sha); 59 | 60 | /* Print the digest as one long hex value */ 61 | printf("0x"); 62 | for (n = 0; n < 20; n++) 63 | printf("%02x", results[n]); 64 | putchar('\n'); 65 | 66 | Alternately, the helper functions could be used in the following way: 67 | 68 | SHA1_CTX sha; 69 | uint8_t output[41]; 70 | char *buf = "abc"; 71 | 72 | printf("0x%s", SHA1Data(buf, strlen(buf), output)); 73 | 74 | AUTHORS 75 | This implementation of SHA-1 was written by Steve Reid. 76 | 77 | BUGS 78 | This implementation of SHA-1 has not been validated by NIST and as such 79 | is not in official compliance with the standard. 80 | 81 | If a message digest is to be copied to a multi-byte type (ie: an array of 82 | five 32-bit integers) it will be necessary to perform byte swapping on 83 | little endian machines such as the i386, alpha, and VAX. 84 | -------------------------------------------------------------------------------- /clib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sha1", 3 | "version": "0.1.0", 4 | "repo": "clibs/sha1", 5 | "description": "sha1 hash algorithm", 6 | "keywords": ["sha1", "hash"], 7 | "license": "public domain", 8 | "src": ["sha1.c", "sha1.h"] 9 | } 10 | -------------------------------------------------------------------------------- /sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | SHA-1 in C 3 | By Steve Reid 4 | 100% Public Domain 5 | 6 | Test Vectors (from FIPS PUB 180-1) 7 | "abc" 8 | A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 9 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 10 | 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 11 | A million repetitions of "a" 12 | 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 13 | */ 14 | 15 | /* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ 16 | /* #define SHA1HANDSOFF * Copies data before messing with it. */ 17 | 18 | #define SHA1HANDSOFF 19 | 20 | #include 21 | #include 22 | 23 | /* for uint32_t */ 24 | #include 25 | 26 | #include "sha1.h" 27 | 28 | 29 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 30 | 31 | /* blk0() and blk() perform the initial expand. */ 32 | /* I got the idea of expanding during the round function from SSLeay */ 33 | #define blk0_le(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 34 | |(rol(block->l[i],8)&0x00FF00FF)) 35 | #define blk0_be(i) block->l[i] 36 | #if BYTE_ORDER == LITTLE_ENDIAN 37 | #define blk0(i) blk0_le(i) 38 | #elif BYTE_ORDER == BIG_ENDIAN 39 | #define blk0(i) blk0_be(i) 40 | #else 41 | /* Fall back to a runtime endian check */ 42 | const union { 43 | long l; 44 | char c; 45 | } sha1_endian = { 1 }; 46 | #define blk0(i) (sha1_endian.c == 0 ? blk0_be(i) : blk0_le(i)) 47 | #endif 48 | 49 | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 50 | ^block->l[(i+2)&15]^block->l[i&15],1)) 51 | 52 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 53 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 54 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 55 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 56 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 57 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 58 | 59 | 60 | /* Hash a single 512-bit block. This is the core of the algorithm. */ 61 | 62 | void SHA1Transform( 63 | uint32_t state[5], 64 | const unsigned char buffer[64] 65 | ) 66 | { 67 | uint32_t a, b, c, d, e; 68 | 69 | typedef union 70 | { 71 | unsigned char c[64]; 72 | uint32_t l[16]; 73 | } CHAR64LONG16; 74 | 75 | #ifdef SHA1HANDSOFF 76 | CHAR64LONG16 block[1]; /* use array to appear as a pointer */ 77 | 78 | memcpy(block, buffer, 64); 79 | #else 80 | /* The following had better never be used because it causes the 81 | * pointer-to-const buffer to be cast into a pointer to non-const. 82 | * And the result is written through. I threw a "const" in, hoping 83 | * this will cause a diagnostic. 84 | */ 85 | CHAR64LONG16 *block = (const CHAR64LONG16 *) buffer; 86 | #endif 87 | /* Copy context->state[] to working vars */ 88 | a = state[0]; 89 | b = state[1]; 90 | c = state[2]; 91 | d = state[3]; 92 | e = state[4]; 93 | /* 4 rounds of 20 operations each. Loop unrolled. */ 94 | R0(a, b, c, d, e, 0); 95 | R0(e, a, b, c, d, 1); 96 | R0(d, e, a, b, c, 2); 97 | R0(c, d, e, a, b, 3); 98 | R0(b, c, d, e, a, 4); 99 | R0(a, b, c, d, e, 5); 100 | R0(e, a, b, c, d, 6); 101 | R0(d, e, a, b, c, 7); 102 | R0(c, d, e, a, b, 8); 103 | R0(b, c, d, e, a, 9); 104 | R0(a, b, c, d, e, 10); 105 | R0(e, a, b, c, d, 11); 106 | R0(d, e, a, b, c, 12); 107 | R0(c, d, e, a, b, 13); 108 | R0(b, c, d, e, a, 14); 109 | R0(a, b, c, d, e, 15); 110 | R1(e, a, b, c, d, 16); 111 | R1(d, e, a, b, c, 17); 112 | R1(c, d, e, a, b, 18); 113 | R1(b, c, d, e, a, 19); 114 | R2(a, b, c, d, e, 20); 115 | R2(e, a, b, c, d, 21); 116 | R2(d, e, a, b, c, 22); 117 | R2(c, d, e, a, b, 23); 118 | R2(b, c, d, e, a, 24); 119 | R2(a, b, c, d, e, 25); 120 | R2(e, a, b, c, d, 26); 121 | R2(d, e, a, b, c, 27); 122 | R2(c, d, e, a, b, 28); 123 | R2(b, c, d, e, a, 29); 124 | R2(a, b, c, d, e, 30); 125 | R2(e, a, b, c, d, 31); 126 | R2(d, e, a, b, c, 32); 127 | R2(c, d, e, a, b, 33); 128 | R2(b, c, d, e, a, 34); 129 | R2(a, b, c, d, e, 35); 130 | R2(e, a, b, c, d, 36); 131 | R2(d, e, a, b, c, 37); 132 | R2(c, d, e, a, b, 38); 133 | R2(b, c, d, e, a, 39); 134 | R3(a, b, c, d, e, 40); 135 | R3(e, a, b, c, d, 41); 136 | R3(d, e, a, b, c, 42); 137 | R3(c, d, e, a, b, 43); 138 | R3(b, c, d, e, a, 44); 139 | R3(a, b, c, d, e, 45); 140 | R3(e, a, b, c, d, 46); 141 | R3(d, e, a, b, c, 47); 142 | R3(c, d, e, a, b, 48); 143 | R3(b, c, d, e, a, 49); 144 | R3(a, b, c, d, e, 50); 145 | R3(e, a, b, c, d, 51); 146 | R3(d, e, a, b, c, 52); 147 | R3(c, d, e, a, b, 53); 148 | R3(b, c, d, e, a, 54); 149 | R3(a, b, c, d, e, 55); 150 | R3(e, a, b, c, d, 56); 151 | R3(d, e, a, b, c, 57); 152 | R3(c, d, e, a, b, 58); 153 | R3(b, c, d, e, a, 59); 154 | R4(a, b, c, d, e, 60); 155 | R4(e, a, b, c, d, 61); 156 | R4(d, e, a, b, c, 62); 157 | R4(c, d, e, a, b, 63); 158 | R4(b, c, d, e, a, 64); 159 | R4(a, b, c, d, e, 65); 160 | R4(e, a, b, c, d, 66); 161 | R4(d, e, a, b, c, 67); 162 | R4(c, d, e, a, b, 68); 163 | R4(b, c, d, e, a, 69); 164 | R4(a, b, c, d, e, 70); 165 | R4(e, a, b, c, d, 71); 166 | R4(d, e, a, b, c, 72); 167 | R4(c, d, e, a, b, 73); 168 | R4(b, c, d, e, a, 74); 169 | R4(a, b, c, d, e, 75); 170 | R4(e, a, b, c, d, 76); 171 | R4(d, e, a, b, c, 77); 172 | R4(c, d, e, a, b, 78); 173 | R4(b, c, d, e, a, 79); 174 | /* Add the working vars back into context.state[] */ 175 | state[0] += a; 176 | state[1] += b; 177 | state[2] += c; 178 | state[3] += d; 179 | state[4] += e; 180 | /* Wipe variables */ 181 | a = b = c = d = e = 0; 182 | #ifdef SHA1HANDSOFF 183 | memset(block, '\0', sizeof(block)); 184 | #endif 185 | } 186 | 187 | 188 | /* SHA1Init - Initialize new context */ 189 | 190 | void SHA1Init( 191 | SHA1_CTX * context 192 | ) 193 | { 194 | /* SHA1 initialization constants */ 195 | context->state[0] = 0x67452301; 196 | context->state[1] = 0xEFCDAB89; 197 | context->state[2] = 0x98BADCFE; 198 | context->state[3] = 0x10325476; 199 | context->state[4] = 0xC3D2E1F0; 200 | context->count[0] = context->count[1] = 0; 201 | } 202 | 203 | 204 | /* Run your data through this. */ 205 | 206 | void SHA1Update( 207 | SHA1_CTX * context, 208 | const unsigned char *data, 209 | uint32_t len 210 | ) 211 | { 212 | uint32_t i; 213 | 214 | uint32_t j; 215 | 216 | j = context->count[0]; 217 | if ((context->count[0] += len << 3) < j) 218 | context->count[1]++; 219 | context->count[1] += (len >> 29); 220 | j = (j >> 3) & 63; 221 | if ((j + len) > 63) 222 | { 223 | memcpy(&context->buffer[j], data, (i = 64 - j)); 224 | SHA1Transform(context->state, context->buffer); 225 | for (; i + 63 < len; i += 64) 226 | { 227 | SHA1Transform(context->state, &data[i]); 228 | } 229 | j = 0; 230 | } 231 | else 232 | i = 0; 233 | memcpy(&context->buffer[j], &data[i], len - i); 234 | } 235 | 236 | 237 | /* Add padding and return the message digest. */ 238 | 239 | void SHA1Final( 240 | unsigned char digest[20], 241 | SHA1_CTX * context 242 | ) 243 | { 244 | unsigned i; 245 | 246 | unsigned char finalcount[8]; 247 | 248 | unsigned char c; 249 | 250 | #if 0 /* untested "improvement" by DHR */ 251 | /* Convert context->count to a sequence of bytes 252 | * in finalcount. Second element first, but 253 | * big-endian order within element. 254 | * But we do it all backwards. 255 | */ 256 | unsigned char *fcp = &finalcount[8]; 257 | 258 | for (i = 0; i < 2; i++) 259 | { 260 | uint32_t t = context->count[i]; 261 | 262 | int j; 263 | 264 | for (j = 0; j < 4; t >>= 8, j++) 265 | *--fcp = (unsigned char) t} 266 | #else 267 | for (i = 0; i < 8; i++) 268 | { 269 | finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ 270 | } 271 | #endif 272 | c = 0200; 273 | SHA1Update(context, &c, 1); 274 | while ((context->count[0] & 504) != 448) 275 | { 276 | c = 0000; 277 | SHA1Update(context, &c, 1); 278 | } 279 | SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 280 | for (i = 0; i < 20; i++) 281 | { 282 | digest[i] = (unsigned char) 283 | ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); 284 | } 285 | /* Wipe variables */ 286 | memset(context, '\0', sizeof(*context)); 287 | memset(&finalcount, '\0', sizeof(finalcount)); 288 | } 289 | 290 | void SHA1( 291 | char *hash_out, 292 | const char *str, 293 | uint32_t len) 294 | { 295 | SHA1_CTX ctx; 296 | unsigned int ii; 297 | 298 | SHA1Init(&ctx); 299 | for (ii=0; ii 7 | 100% Public Domain 8 | */ 9 | 10 | #include "stdint.h" 11 | 12 | #if defined(__cplusplus) 13 | extern "C" { 14 | #endif 15 | 16 | typedef struct 17 | { 18 | uint32_t state[5]; 19 | uint32_t count[2]; 20 | unsigned char buffer[64]; 21 | } SHA1_CTX; 22 | 23 | void SHA1Transform( 24 | uint32_t state[5], 25 | const unsigned char buffer[64] 26 | ); 27 | 28 | void SHA1Init( 29 | SHA1_CTX * context 30 | ); 31 | 32 | void SHA1Update( 33 | SHA1_CTX * context, 34 | const unsigned char *data, 35 | uint32_t len 36 | ); 37 | 38 | void SHA1Final( 39 | unsigned char digest[20], 40 | SHA1_CTX * context 41 | ); 42 | 43 | void SHA1( 44 | char *hash_out, 45 | const char *str, 46 | uint32_t len); 47 | 48 | #if defined(__cplusplus) 49 | } 50 | #endif 51 | 52 | #endif /* SHA1_H */ 53 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | /* 2 | SHA1 tests by Philip Woolford 3 | 100% Public Domain 4 | */ 5 | 6 | #include "sha1.h" 7 | #include "CUnit/Basic.h" 8 | #include "stdio.h" 9 | #include "string.h" 10 | 11 | #define SUCCESS 0 12 | 13 | /* The suite initialization function. 14 | * Returns zero on success, non-zero otherwise. 15 | */ 16 | int init_suite( 17 | void 18 | ) 19 | { 20 | return 0; 21 | } 22 | 23 | /* The suite cleanup function. 24 | * Returns zero on success, non-zero otherwise. 25 | */ 26 | int clean_suite( 27 | void 28 | ) 29 | { 30 | return 0; 31 | } 32 | 33 | /* Test Vector 1 */ 34 | void testvec1( 35 | void 36 | ) 37 | { 38 | char const string[] = "abc"; 39 | char const expect[] = "a9993e364706816aba3e25717850c26c9cd0d89d"; 40 | char result[21]; 41 | char hexresult[41]; 42 | size_t offset; 43 | 44 | /* calculate hash */ 45 | SHA1( result, string, strlen(string) ); 46 | 47 | /* format the hash for comparison */ 48 | for( offset = 0; offset < 20; offset++) { 49 | sprintf( ( hexresult + (2*offset)), "%02x", result[offset]&0xff); 50 | } 51 | 52 | CU_ASSERT( strncmp(hexresult, expect, 40) == SUCCESS ); 53 | } 54 | 55 | /* Test Vector 2 */ 56 | void testvec2( 57 | void 58 | ) 59 | { 60 | char const string[] = ""; 61 | char const expect[] = "da39a3ee5e6b4b0d3255bfef95601890afd80709"; 62 | char result[21]; 63 | char hexresult[41]; 64 | size_t offset; 65 | 66 | /* calculate hash */ 67 | SHA1( result, string, strlen(string) ); 68 | 69 | /*format the hash for comparison */ 70 | for( offset = 0; offset < 20; offset++) { 71 | sprintf( ( hexresult + (2*offset)), "%02x", result[offset]&0xff); 72 | } 73 | 74 | CU_ASSERT( strncmp(hexresult, expect, 40) == SUCCESS ); 75 | } 76 | 77 | /* Test Vector 3 */ 78 | void testvec3( 79 | void 80 | ) 81 | { 82 | char const string[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; 83 | char const expect[] = "84983e441c3bd26ebaae4aa1f95129e5e54670f1"; 84 | char result[21]; 85 | char hexresult[41]; 86 | size_t offset; 87 | 88 | /* calculate hash */ 89 | SHA1( result, string, strlen(string) ); 90 | 91 | /* format the hash for comparison */ 92 | for( offset = 0; offset < 20; offset++) { 93 | sprintf( ( hexresult + (2*offset)), "%02x", result[offset]&0xff); 94 | } 95 | 96 | CU_ASSERT( strncmp(hexresult, expect, 40) == SUCCESS ); 97 | } 98 | 99 | /* Test Vector 4 */ 100 | void testvec4( 101 | void 102 | ) 103 | { 104 | char const string1[] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghij"; 105 | char const string2[] = "klmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; 106 | char const expect[] = "a49b2446a02c645bf419f995b67091253a04a259"; 107 | unsigned char result[21]; 108 | char hexresult[41]; 109 | size_t offset; 110 | SHA1_CTX ctx; 111 | 112 | /* calculate hash */ 113 | SHA1Init(&ctx); 114 | SHA1Update( &ctx, (unsigned char const *)string1, strlen(string1) ); 115 | SHA1Update( &ctx, (unsigned char const *)string2, strlen(string2) ); 116 | SHA1Final(result, &ctx); 117 | 118 | /* format the hash for comparison */ 119 | for( offset = 0; offset < 20; offset++) { 120 | sprintf( ( hexresult + (2*offset)), "%02x", result[offset]&0xff); 121 | } 122 | 123 | CU_ASSERT( strncmp(hexresult, expect, 40) == SUCCESS ); 124 | } 125 | 126 | /* Test Vector 5 */ 127 | void testvec5( 128 | void 129 | ) 130 | { 131 | char string[1000001]; 132 | char const expect[] = "34aa973cd4c4daa4f61eeb2bdbad27316534016f"; 133 | char result[21]; 134 | char hexresult[41]; 135 | int iterator; 136 | size_t offset; 137 | 138 | /* generate string */ 139 | for( iterator = 0; iterator < 1000000; iterator++) { 140 | string[iterator] = 'a'; 141 | } 142 | string[1000000] = '\0'; 143 | 144 | /* calculate hash */ 145 | SHA1( result, string, strlen(string) ); 146 | 147 | /* format the hash for comparison */ 148 | for( offset = 0; offset < 20; offset++) { 149 | sprintf( ( hexresult + (2*offset)), "%02x", result[offset]&0xff); 150 | } 151 | 152 | CU_ASSERT( strncmp(hexresult, expect, 40) == SUCCESS ); 153 | } 154 | 155 | /* Test Vector 6 */ 156 | void testvec6( 157 | void 158 | ) 159 | { 160 | char const string[] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"; 161 | char const expect[] = "7789f0c9ef7bfc40d93311143dfbe69e2017f592"; 162 | unsigned char result[21]; 163 | char hexresult[41]; 164 | int iterator; 165 | size_t offset; 166 | SHA1_CTX ctx; 167 | 168 | /* calculate hash */ 169 | SHA1Init(&ctx); 170 | for ( iterator = 0; iterator < 16777216; iterator++) { 171 | SHA1Update( &ctx, (unsigned char const *)string, strlen(string) ); 172 | } 173 | SHA1Final(result, &ctx); 174 | 175 | /* format the hash for comparison */ 176 | for( offset = 0; offset < 20; offset++) { 177 | sprintf( ( hexresult + (2*offset)), "%02x", result[offset]&0xff); 178 | } 179 | 180 | CU_ASSERT( strncmp(hexresult, expect, 40) == SUCCESS ); 181 | } 182 | 183 | int main( 184 | void 185 | ) 186 | { 187 | CU_pSuite pSuite = NULL; 188 | 189 | /* initialize the CUnit test registry */ 190 | if (CUE_SUCCESS != CU_initialize_registry()) 191 | return CU_get_error(); 192 | 193 | /* add a suite to the registry */ 194 | pSuite = CU_add_suite("http://www.di-mgt.com.au/sha_testvectors.html", init_suite, clean_suite); 195 | if (NULL == pSuite) { 196 | CU_cleanup_registry(); 197 | return CU_get_error(); 198 | } 199 | 200 | /* add the tests to the suite */ 201 | if ((NULL == CU_add_test(pSuite, "Test of Test Vector 1", testvec1)) || 202 | (NULL == CU_add_test(pSuite, "Test of Test Vector 2", testvec2)) || 203 | (NULL == CU_add_test(pSuite, "Test of Test Vector 3", testvec3)) || 204 | (NULL == CU_add_test(pSuite, "Test of Test Vector 4", testvec4)) || 205 | (NULL == CU_add_test(pSuite, "Test of Test Vector 5", testvec5)) || 206 | (NULL == CU_add_test(pSuite, "Test of Test Vector 6", testvec6))) 207 | { 208 | CU_cleanup_registry(); 209 | return CU_get_error(); 210 | } 211 | 212 | /* Run all tests using the CUnit Basic interface */ 213 | CU_basic_set_mode(CU_BRM_VERBOSE); 214 | CU_basic_run_tests(); 215 | CU_cleanup_registry(); 216 | return CU_get_error(); 217 | } 218 | --------------------------------------------------------------------------------