소스 검색

Adjust data types in sha1.inl and add test for SHA1

bel 8 년 전
부모
커밋
d8be6938ab
3개의 변경된 파일107개의 추가작업 그리고 34개의 파일을 삭제
  1. 28 33
      src/sha1.inl
  2. 1 0
      test/CMakeLists.txt
  3. 78 1
      test/private.c

+ 28 - 33
src/sha1.inl

@@ -114,16 +114,13 @@ blk0(CHAR64LONG16 *block, int i)
 	static const uint32_t n = 1u;
 	static const uint32_t n = 1u;
 	if ((*((uint8_t *)(&n))) == 1) {
 	if ((*((uint8_t *)(&n))) == 1) {
 		/* little endian / intel byte order */
 		/* little endian / intel byte order */
-		return (rol(block->l[i], 24) & 0xFF00FF00)
-		       | (rol(block->l[i], 8) & 0x00FF00FF);
-	} else {
-		/* big endian / motorola byte order */
-		return block->l[i];
+		block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00)
+		              | (rol(block->l[i], 8) & 0x00FF00FF);
 	}
 	}
+	return block->l[i];
 }
 }
 
 
-
-#define blk(i)                                                                 \
+#define blk(block, i)                                                          \
 	(block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15]   \
 	(block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15]   \
 	                            ^ block->l[(i + 2) & 15] ^ block->l[i & 15],   \
 	                            ^ block->l[(i + 2) & 15] ^ block->l[i & 15],   \
 	                        1))
 	                        1))
@@ -133,16 +130,16 @@ blk0(CHAR64LONG16 *block, int i)
 	z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5);        \
 	z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5);        \
 	w = rol(w, 30);
 	w = rol(w, 30);
 #define R1(v, w, x, y, z, i)                                                   \
 #define R1(v, w, x, y, z, i)                                                   \
-	z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5);                \
+	z += ((w & (x ^ y)) ^ y) + blk(block, i) + 0x5A827999 + rol(v, 5);         \
 	w = rol(w, 30);
 	w = rol(w, 30);
 #define R2(v, w, x, y, z, i)                                                   \
 #define R2(v, w, x, y, z, i)                                                   \
-	z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5);                        \
+	z += (w ^ x ^ y) + blk(block, i) + 0x6ED9EBA1 + rol(v, 5);                 \
 	w = rol(w, 30);
 	w = rol(w, 30);
 #define R3(v, w, x, y, z, i)                                                   \
 #define R3(v, w, x, y, z, i)                                                   \
-	z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5);          \
+	z += (((w | x) & y) | (w & x)) + blk(block, i) + 0x8F1BBCDC + rol(v, 5);   \
 	w = rol(w, 30);
 	w = rol(w, 30);
 #define R4(v, w, x, y, z, i)                                                   \
 #define R4(v, w, x, y, z, i)                                                   \
-	z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5);                        \
+	z += (w ^ x ^ y) + blk(block, i) + 0xCA62C1D6 + rol(v, 5);                 \
 	w = rol(w, 30);
 	w = rol(w, 30);
 
 
 
 
@@ -151,13 +148,10 @@ static void
 SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
 SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
 {
 {
 	uint32_t a, b, c, d, e;
 	uint32_t a, b, c, d, e;
-	CHAR64LONG16 *block;
-
-	/* Must use an aligned buffer */
-	CHAR64LONG16 aligned_buf;
-	memcpy(&aligned_buf, &buffer, sizeof(aligned_buf));
 
 
-	block = &aligned_buf;
+	/* Must use an aligned, read/write buffer */
+	CHAR64LONG16 block[1];
+	memcpy(block, buffer, sizeof(block));
 
 
 	/* Copy context->state[] to working vars */
 	/* Copy context->state[] to working vars */
 	a = state[0];
 	a = state[0];
@@ -274,25 +268,28 @@ SHA1_Init(SHA1_CTX *context)
 }
 }
 
 
 
 
-/* Run your data through this. */
 SHA_API void
 SHA_API void
 SHA1_Update(SHA1_CTX *context, const uint8_t *data, const uint32_t len)
 SHA1_Update(SHA1_CTX *context, const uint8_t *data, const uint32_t len)
 {
 {
-	size_t i, j;
+	uint32_t i, j;
 
 
-	j = (context->count[0] >> 3) & 63;
-	if ((context->count[0] += len << 3) < (len << 3))
+	j = context->count[0];
+	if ((context->count[0] += (len << 3)) < j) {
 		context->count[1]++;
 		context->count[1]++;
+	}
 	context->count[1] += (len >> 29);
 	context->count[1] += (len >> 29);
+	j = (j >> 3) & 63;
 	if ((j + len) > 63) {
 	if ((j + len) > 63) {
-		memcpy(&context->buffer[j], data, (i = 64 - j));
+		i = 64 - j;
+		memcpy(&context->buffer[j], data, i);
 		SHA1_Transform(context->state, context->buffer);
 		SHA1_Transform(context->state, context->buffer);
 		for (; i + 63 < len; i += 64) {
 		for (; i + 63 < len; i += 64) {
-			SHA1_Transform(context->state, data + i);
+			SHA1_Transform(context->state, &data[i]);
 		}
 		}
 		j = 0;
 		j = 0;
-	} else
+	} else {
 		i = 0;
 		i = 0;
+	}
 	memcpy(&context->buffer[j], &data[i], len - i);
 	memcpy(&context->buffer[j], &data[i], len - i);
 }
 }
 
 
@@ -305,13 +302,13 @@ SHA1_Final(SHA1_CTX *context, uint8_t digest[SHA1_DIGEST_SIZE])
 	uint8_t finalcount[8];
 	uint8_t finalcount[8];
 
 
 	for (i = 0; i < 8; i++) {
 	for (i = 0; i < 8; i++) {
-		finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
-		                                 >> ((3 - (i & 3)) * 8))
-		                                & 255); /* Endian independent */
+		finalcount[i] =
+		    (uint8_t)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8))
+		              & 255); /* Endian independent */
 	}
 	}
-	SHA1_Update(context, (uint8_t *)"\200", 1);
+	SHA1_Update(context, (uint8_t *)"\x80", 1);
 	while ((context->count[0] & 504) != 448) {
 	while ((context->count[0] & 504) != 448) {
-		SHA1_Update(context, (uint8_t *)"\0", 1);
+		SHA1_Update(context, (uint8_t *)"\x00", 1);
 	}
 	}
 	SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
 	SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
 	for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
 	for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
@@ -321,8 +318,6 @@ SHA1_Final(SHA1_CTX *context, uint8_t digest[SHA1_DIGEST_SIZE])
 
 
 	/* Wipe variables */
 	/* Wipe variables */
 	i = 0;
 	i = 0;
-	memset(context->buffer, 0, 64);
-	memset(context->state, 0, 20);
-	memset(context->count, 0, 8);
-	memset(finalcount, 0, 8); /* SWR */
+	memset(context, '\0', sizeof(*context));
+	memset(&finalcount, '\0', sizeof(finalcount));
 }
 }

+ 1 - 0
test/CMakeLists.txt

@@ -139,6 +139,7 @@ civetweb_add_test(Private "Internal Parsing")
 civetweb_add_test(Private "Encode Decode")
 civetweb_add_test(Private "Encode Decode")
 civetweb_add_test(Private "Mask Data")
 civetweb_add_test(Private "Mask Data")
 civetweb_add_test(Private "Date Parsing")
 civetweb_add_test(Private "Date Parsing")
+civetweb_add_test(Private "SHA1")
 
 
 # Public API function tests
 # Public API function tests
 civetweb_add_test(PublicFunc "Version")
 civetweb_add_test(PublicFunc "Version")

+ 78 - 1
test/private.c

@@ -664,6 +664,77 @@ START_TEST(test_parse_date_string)
 END_TEST
 END_TEST
 
 
 
 
+START_TEST(test_sha1)
+{
+#ifdef SHA1_DIGEST_SIZE
+	SHA1_CTX sha_ctx;
+	uint8_t digest[SHA1_DIGEST_SIZE] = {0};
+	char str[48] = {0};
+	int i;
+	const char *test_str;
+
+	ck_assert_uint_eq(sizeof(digest), 20);
+	ck_assert_uint_gt(sizeof(str), sizeof(digest) * 2 + 1);
+
+	/* empty string */
+	SHA1_Init(&sha_ctx);
+	SHA1_Final(&sha_ctx, digest);
+	bin2str(str, digest, sizeof(digest));
+	ck_assert_uint_eq(strlen(str), 40);
+	ck_assert_str_eq(str, "da39a3ee5e6b4b0d3255bfef95601890afd80709");
+
+	/* empty string */
+	SHA1_Init(&sha_ctx);
+	SHA1_Update(&sha_ctx, "abc", 0);
+	SHA1_Final(&sha_ctx, digest);
+	bin2str(str, digest, sizeof(digest));
+	ck_assert_uint_eq(strlen(str), 40);
+	ck_assert_str_eq(str, "da39a3ee5e6b4b0d3255bfef95601890afd80709");
+
+	/* "abc" */
+	SHA1_Init(&sha_ctx);
+	SHA1_Update(&sha_ctx, "abc", 3);
+	SHA1_Final(&sha_ctx, digest);
+	bin2str(str, digest, sizeof(digest));
+	ck_assert_uint_eq(strlen(str), 40);
+	ck_assert_str_eq(str, "a9993e364706816aba3e25717850c26c9cd0d89d");
+
+	/* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" */
+	test_str = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+	SHA1_Init(&sha_ctx);
+	SHA1_Update(&sha_ctx, test_str, strlen(test_str));
+	SHA1_Final(&sha_ctx, digest);
+	bin2str(str, digest, sizeof(digest));
+	ck_assert_uint_eq(strlen(str), 40);
+	ck_assert_str_eq(str, "84983e441c3bd26ebaae4aa1f95129e5e54670f1");
+
+	/* a million "a" */
+	SHA1_Init(&sha_ctx);
+	for (i = 0; i < 1000000; i++) {
+		SHA1_Update(&sha_ctx, "a", 1);
+	}
+	SHA1_Final(&sha_ctx, digest);
+	bin2str(str, digest, sizeof(digest));
+	ck_assert_uint_eq(strlen(str), 40);
+	ck_assert_str_eq(str, "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
+
+	/* a million "a" in blocks of 10 */
+	SHA1_Init(&sha_ctx);
+	for (i = 0; i < 100000; i++) {
+		SHA1_Update(&sha_ctx, "aaaaaaaaaa", 10);
+	}
+	SHA1_Final(&sha_ctx, digest);
+	bin2str(str, digest, sizeof(digest));
+	ck_assert_uint_eq(strlen(str), 40);
+	ck_assert_str_eq(str, "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
+#else
+	/* Can not test, if SHA1 is not included */
+	ck_assert(1);
+#endif
+}
+END_TEST
+
+
 Suite *
 Suite *
 make_private_suite(void)
 make_private_suite(void)
 {
 {
@@ -675,6 +746,7 @@ make_private_suite(void)
 	TCase *const tcase_encode_decode = tcase_create("Encode Decode");
 	TCase *const tcase_encode_decode = tcase_create("Encode Decode");
 	TCase *const tcase_mask_data = tcase_create("Mask Data");
 	TCase *const tcase_mask_data = tcase_create("Mask Data");
 	TCase *const tcase_parse_date_string = tcase_create("Date Parsing");
 	TCase *const tcase_parse_date_string = tcase_create("Date Parsing");
+	TCase *const tcase_sha1 = tcase_create("SHA1");
 
 
 	tcase_add_test(tcase_http_message, test_parse_http_message);
 	tcase_add_test(tcase_http_message, test_parse_http_message);
 	tcase_add_test(tcase_http_message, test_should_keep_alive);
 	tcase_add_test(tcase_http_message, test_should_keep_alive);
@@ -706,9 +778,13 @@ make_private_suite(void)
 	suite_add_tcase(suite, tcase_mask_data);
 	suite_add_tcase(suite, tcase_mask_data);
 
 
 	tcase_add_test(tcase_parse_date_string, test_parse_date_string);
 	tcase_add_test(tcase_parse_date_string, test_parse_date_string);
-	tcase_set_timeout(tcase_mask_data, civetweb_min_test_timeout);
+	tcase_set_timeout(tcase_parse_date_string, civetweb_min_test_timeout);
 	suite_add_tcase(suite, tcase_parse_date_string);
 	suite_add_tcase(suite, tcase_parse_date_string);
 
 
+	tcase_add_test(tcase_sha1, test_sha1);
+	tcase_set_timeout(tcase_sha1, civetweb_min_test_timeout);
+	suite_add_tcase(suite, tcase_sha1);
+
 	return suite;
 	return suite;
 }
 }
 
 
@@ -731,6 +807,7 @@ MAIN_PRIVATE(void)
 	test_parse_date_string(0);
 	test_parse_date_string(0);
 	test_parse_port_string(0);
 	test_parse_port_string(0);
 	test_parse_http_message(0);
 	test_parse_http_message(0);
+	test_sha1(0);
 }
 }
 
 
 #endif
 #endif