sha1dc: update from upstream

Update sha1dc from the latest version by the upstream maintainer[1]. This version includes a commit of mine which allows for replacing the local modifications done to the upstream files in git.git with macro definitions to monkeypatch it in place. It also brings in a change[2] upstream made for the breakage 2.13.0 introduced on SPARC and other platforms that forbid unaligned access[3]. This means that the code customizations done since the initial import in commit 28dc98e343 ("sha1dc: add collision-detecting sha1 implementation", 2017-03-16) can be done purely via Makefile definitions and by including the content of our own sha1dc_git.[ch] in sha1dc/sha1.c via a macro. 1. https://github.com/cr-marcstevens/sha1collisiondetection/commit/cc465543b310e5f59a1d534381690052e8509b22 2. https://github.com/cr-marcstevens/sha1collisiondetection/commit/33a694a9ee1b79c24be45f9eab5ac0e1aeeaf271 3. "Git 2.13.0 segfaults on Solaris SPARC due to DC_SHA1=YesPlease being on by default" (https://public-inbox.org/git/CACBZZX6nmKK8af0-UpjCKWV4R+hV-uk2xWXVA5U+_UQ3VXU03g@mail.gmail.com/) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed May 20, 2017 at 11:54 UTC a0103914c228cee430b37faab212d1769e8218a0
7 files changed +172 -88
Makefile
+8 -1
@@ -1414,7 +1414,14 @@ else
1414 DC_SHA1 := YesPlease
1415 LIB_OBJS += sha1dc/sha1.o
1416 LIB_OBJS += sha1dc/ubc_check.o
1417 - BASIC_CFLAGS += -DSHA1_DC
1417 + BASIC_CFLAGS += \
1418 + -DSHA1_DC \
1419 + -DSHA1DC_NO_STANDARD_INCLUDES \
1420 + -DSHA1DC_INIT_SAFE_HASH_DEFAULT=0 \
1421 + -DSHA1DC_CUSTOM_INCLUDE_SHA1_C="\"cache.h\"" \
1422 + -DSHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_C="\"sha1dc_git.c\"" \
1423 + -DSHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H="\"sha1dc_git.h\"" \
1424 + -DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="\"git-compat-util.h\""
1425 endif
1426 endif
1427 endif
sha1dc/sha1.c
+60 -31
@@ -5,9 +5,23 @@
5 * https://opensource.org/licenses/MIT
6 ***/
7
8 -#include "cache.h"
9 -#include "sha1dc/sha1.h"
10 -#include "sha1dc/ubc_check.h"
8 +#ifndef SHA1DC_NO_STANDARD_INCLUDES
9 +#include <string.h>
10 +#include <memory.h>
11 +#include <stdio.h>
12 +#include <stdlib.h>
13 +#endif
14 +
15 +#ifdef SHA1DC_CUSTOM_INCLUDE_SHA1_C
16 +#include SHA1DC_CUSTOM_INCLUDE_SHA1_C
17 +#endif
18 +
19 +#ifndef SHA1DC_INIT_SAFE_HASH_DEFAULT
20 +#define SHA1DC_INIT_SAFE_HASH_DEFAULT 1
21 +#endif
22 +
23 +#include "sha1.h"
24 +#include "ubc_check.h"
25
26
27 /*
@@ -18,16 +32,31 @@
32 If you are compiling on a big endian platform and your compiler does not define one of these,
33 you will have to add whatever macros your tool chain defines to indicate Big-Endianness.
34 */
21 -#if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || \
35 +#ifdef SHA1DC_BIGENDIAN
36 +#undef SHA1DC_BIGENDIAN
37 +#endif
38 +#if (!defined SHA1DC_FORCE_LITTLEENDIAN) && \
39 + ((defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || \
40 (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)) || \
23 - defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
24 - defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
41 + defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
42 + defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) || defined(SHA1DC_FORCE_BIGENDIAN))
43 +
44 +#define SHA1DC_BIGENDIAN
45
26 -#define SHA1DC_BIGENDIAN 1
27 -#else
28 -#undef SHA1DC_BIGENDIAN
46 #endif /*ENDIANNESS SELECTION*/
47
48 +#if (defined SHA1DC_FORCE_UNALIGNED_ACCESS || \
49 + defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
50 + defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || \
51 + defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || \
52 + defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || \
53 + defined(__386) || defined(_M_X64) || defined(_M_AMD64))
54 +
55 +#define SHA1DC_ALLOW_UNALIGNED_ACCESS
56 +
57 +#endif /*UNALIGNMENT DETECTION*/
58 +
59 +
60 #define rotate_right(x,n) (((x)>>(n))|((x)<<(32-(n))))
61 #define rotate_left(x,n) (((x)<<(n))|((x)>>(32-(n))))
62
@@ -36,11 +65,11 @@
65
66 #define sha1_mix(W, t) (rotate_left(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1))
67
39 -#if defined(SHA1DC_BIGENDIAN)
68 +#ifdef SHA1DC_BIGENDIAN
69 #define sha1_load(m, t, temp) { temp = m[t]; }
70 #else
71 #define sha1_load(m, t, temp) { temp = m[t]; sha1_bswap32(temp); }
43 -#endif /* !defined(SHA1DC_BIGENDIAN) */
72 +#endif
73
74 #define sha1_store(W, t, x) *(volatile uint32_t *)&W[t] = x
75
@@ -869,6 +898,11 @@ static void sha1recompress_fast_ ## t (uint32_t ihvin[5], uint32_t ihvout[5], co
898 ihvout[0] = ihvin[0] + a; ihvout[1] = ihvin[1] + b; ihvout[2] = ihvin[2] + c; ihvout[3] = ihvin[3] + d; ihvout[4] = ihvin[4] + e; \
899 }
900
901 +#ifdef _MSC_VER
902 +#pragma warning(push)
903 +#pragma warning(disable: 4127) /* Complier complains about the checks in the above macro being constant. */
904 +#endif
905 +
906 #ifdef DOSTORESTATE0
907 SHA1_RECOMPRESS(0)
908 #endif
@@ -1189,6 +1223,10 @@ SHA1_RECOMPRESS(78)
1223 SHA1_RECOMPRESS(79)
1224 #endif
1225
1226 +#ifdef _MSC_VER
1227 +#pragma warning(pop)
1228 +#endif
1229 +
1230 static void sha1_recompression_step(uint32_t step, uint32_t ihvin[5], uint32_t ihvout[5], const uint32_t me2[80], const uint32_t state[5])
1231 {
1232 switch (step)
@@ -1662,7 +1700,7 @@ void SHA1DCInit(SHA1_CTX* ctx)
1700 ctx->ihv[3] = 0x10325476;
1701 ctx->ihv[4] = 0xC3D2E1F0;
1702 ctx->found_collision = 0;
1665 - ctx->safe_hash = 0;
1703 + ctx->safe_hash = SHA1DC_INIT_SAFE_HASH_DEFAULT;
1704 ctx->ubc_check = 1;
1705 ctx->detect_coll = 1;
1706 ctx->reduced_round_coll = 0;
@@ -1710,6 +1748,7 @@ void SHA1DCSetCallback(SHA1_CTX* ctx, collision_block_callback callback)
1748 void SHA1DCUpdate(SHA1_CTX* ctx, const char* buf, size_t len)
1749 {
1750 unsigned left, fill;
1751 +
1752 if (len == 0)
1753 return;
1754
@@ -1728,7 +1767,13 @@ void SHA1DCUpdate(SHA1_CTX* ctx, const char* buf, size_t len)
1767 while (len >= 64)
1768 {
1769 ctx->total += 64;
1770 +
1771 +#if defined(SHA1DC_ALLOW_UNALIGNED_ACCESS)
1772 sha1_process(ctx, (uint32_t*)(buf));
1773 +#else
1774 + memcpy(ctx->buffer, buf, 64);
1775 + sha1_process(ctx, (uint32_t*)(ctx->buffer));
1776 +#endif /* defined(SHA1DC_ALLOW_UNALIGNED_ACCESS) */
1777 buf += 64;
1778 len -= 64;
1779 }
@@ -1788,22 +1833,6 @@ int SHA1DCFinal(unsigned char output[20], SHA1_CTX *ctx)
1833 return ctx->found_collision;
1834 }
1835
1791 -void git_SHA1DCFinal(unsigned char hash[20], SHA1_CTX *ctx)
1792 -{
1793 - if (!SHA1DCFinal(hash, ctx))
1794 - return;
1795 - die("SHA-1 appears to be part of a collision attack: %s",
1796 - sha1_to_hex(hash));
1797 -}
1798 -
1799 -void git_SHA1DCUpdate(SHA1_CTX *ctx, const void *vdata, unsigned long len)
1800 -{
1801 - const char *data = vdata;
1802 - /* We expect an unsigned long, but sha1dc only takes an int */
1803 - while (len > INT_MAX) {
1804 - SHA1DCUpdate(ctx, data, INT_MAX);
1805 - data += INT_MAX;
1806 - len -= INT_MAX;
1807 - }
1808 - SHA1DCUpdate(ctx, data, len);
1809 -}
1836 +#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_C
1837 +#include SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_C
1838 +#endif
sha1dc/sha1.h
+39 -51
@@ -4,6 +4,7 @@
4 * See accompanying file LICENSE.txt or copy at
5 * https://opensource.org/licenses/MIT
6 ***/
7 +
8 #ifndef SHA1DC_SHA1_H
9 #define SHA1DC_SHA1_H
10
@@ -11,36 +12,30 @@
12 extern "C" {
13 #endif
14
14 -/* uses SHA-1 message expansion to expand the first 16 words of W[] to 80 words */
15 -/* void sha1_message_expansion(uint32_t W[80]); */
16 -
17 -/* sha-1 compression function; first version takes a message block pre-parsed as 16 32-bit integers, second version takes an already expanded message) */
18 -/* void sha1_compression(uint32_t ihv[5], const uint32_t m[16]);
19 -void sha1_compression_W(uint32_t ihv[5], const uint32_t W[80]); */
15 +#ifndef SHA1DC_NO_STANDARD_INCLUDES
16 +#include <stdint.h>
17 +#endif
18
21 -/* same as sha1_compression_W, but additionally store intermediate states */
19 +/* sha-1 compression function that takes an already expanded message, and additionally store intermediate states */
20 /* only stores states ii (the state between step ii-1 and step ii) when DOSTORESTATEii is defined in ubc_check.h */
21 void sha1_compression_states(uint32_t[5], const uint32_t[16], uint32_t[80], uint32_t[80][5]);
22
23 /*
26 -// function type for sha1_recompression_step_T (uint32_t ihvin[5], uint32_t ihvout[5], const uint32_t me2[80], const uint32_t state[5])
27 -// where 0 <= T < 80
28 -// me2 is an expanded message (the expansion of an original message block XOR'ed with a disturbance vector's message block difference)
29 -// state is the internal state (a,b,c,d,e) before step T of the SHA-1 compression function while processing the original message block
30 -// the function will return:
31 -// ihvin: the reconstructed input chaining value
32 -// ihvout: the reconstructed output chaining value
24 +// Function type for sha1_recompression_step_T (uint32_t ihvin[5], uint32_t ihvout[5], const uint32_t me2[80], const uint32_t state[5]).
25 +// Where 0 <= T < 80
26 +// me2 is an expanded message (the expansion of an original message block XOR'ed with a disturbance vector's message block difference.)
27 +// state is the internal state (a,b,c,d,e) before step T of the SHA-1 compression function while processing the original message block.
28 +// The function will return:
29 +// ihvin: The reconstructed input chaining value.
30 +// ihvout: The reconstructed output chaining value.
31 */
32 typedef void(*sha1_recompression_type)(uint32_t*, uint32_t*, const uint32_t*, const uint32_t*);
33
36 -/* table of sha1_recompression_step_0, ... , sha1_recompression_step_79 */
37 -/* extern sha1_recompression_type sha1_recompression_step[80];*/
38 -
39 -/* a callback function type that can be set to be called when a collision block has been found: */
34 +/* A callback function type that can be set to be called when a collision block has been found: */
35 /* void collision_block_callback(uint64_t byteoffset, const uint32_t ihvin1[5], const uint32_t ihvin2[5], const uint32_t m1[80], const uint32_t m2[80]) */
36 typedef void(*collision_block_callback)(uint64_t, const uint32_t*, const uint32_t*, const uint32_t*, const uint32_t*);
37
43 -/* the SHA-1 context */
38 +/* The SHA-1 context. */
39 typedef struct {
40 uint64_t total;
41 uint32_t ihv[5];
@@ -59,30 +54,34 @@ typedef struct {
54 uint32_t states[80][5];
55 } SHA1_CTX;
56
62 -/* initialize SHA-1 context */
57 +/* Initialize SHA-1 context. */
58 void SHA1DCInit(SHA1_CTX*);
59
60 /*
66 -// function to enable safe SHA-1 hashing:
67 -// collision attacks are thwarted by hashing a detected near-collision block 3 times
68 -// think of it as extending SHA-1 from 80-steps to 240-steps for such blocks:
69 -// the best collision attacks against SHA-1 have complexity about 2^60,
70 -// thus for 240-steps an immediate lower-bound for the best cryptanalytic attacks would 2^180
71 -// an attacker would be better off using a generic birthday search of complexity 2^80
72 -//
73 -// enabling safe SHA-1 hashing will result in the correct SHA-1 hash for messages where no collision attack was detected
74 -// but it will result in a different SHA-1 hash for messages where a collision attack was detected
75 -// this will automatically invalidate SHA-1 based digital signature forgeries
76 -// enabled by default
61 + Function to enable safe SHA-1 hashing:
62 + Collision attacks are thwarted by hashing a detected near-collision block 3 times.
63 + Think of it as extending SHA-1 from 80-steps to 240-steps for such blocks:
64 + The best collision attacks against SHA-1 have complexity about 2^60,
65 + thus for 240-steps an immediate lower-bound for the best cryptanalytic attacks would be 2^180.
66 + An attacker would be better off using a generic birthday search of complexity 2^80.
67 +
68 + Enabling safe SHA-1 hashing will result in the correct SHA-1 hash for messages where no collision attack was detected,
69 + but it will result in a different SHA-1 hash for messages where a collision attack was detected.
70 + This will automatically invalidate SHA-1 based digital signature forgeries.
71 + Enabled by default.
72 */
73 void SHA1DCSetSafeHash(SHA1_CTX*, int);
74
80 -/* function to disable or enable the use of Unavoidable Bitconditions (provides a significant speed up) */
81 -/* enabled by default */
75 +/*
76 + Function to disable or enable the use of Unavoidable Bitconditions (provides a significant speed up).
77 + Enabled by default
78 + */
79 void SHA1DCSetUseUBC(SHA1_CTX*, int);
80
84 -/* function to disable or enable the use of Collision Detection */
85 -/* enabled by default */
81 +/*
82 + Function to disable or enable the use of Collision Detection.
83 + Enabled by default.
84 + */
85 void SHA1DCSetUseDetectColl(SHA1_CTX*, int);
86
87 /* function to disable or enable the detection of reduced-round SHA-1 collisions */
@@ -100,23 +99,12 @@ void SHA1DCUpdate(SHA1_CTX*, const char*, size_t);
99 /* returns: 0 = no collision detected, otherwise = collision found => warn user for active attack */
100 int SHA1DCFinal(unsigned char[20], SHA1_CTX*);
101
103 -/*
104 - * Same as SHA1DCFinal, but convert collision attack case into a verbose die().
105 - */
106 -void git_SHA1DCFinal(unsigned char [20], SHA1_CTX *);
107 -
108 -/*
109 - * Same as SHA1DCUpdate, but adjust types to match git's usual interface.
110 - */
111 -void git_SHA1DCUpdate(SHA1_CTX *ctx, const void *data, unsigned long len);
112 -
113 -#define platform_SHA_CTX SHA1_CTX
114 -#define platform_SHA1_Init SHA1DCInit
115 -#define platform_SHA1_Update git_SHA1DCUpdate
116 -#define platform_SHA1_Final git_SHA1DCFinal
117 -
102 #if defined(__cplusplus)
103 }
104 #endif
105
122 -#endif /* SHA1DC_SHA1_H */
106 +#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H
107 +#include SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H
108 +#endif
109 +
110 +#endif
sha1dc/ubc_check.c
+11 -2
@@ -24,8 +24,13 @@
24 // ubc_check has been verified against ubc_check_verify using the 'ubc_check_test' program in the tools section
25 */
26
27 -#include "git-compat-util.h"
28 -#include "sha1dc/ubc_check.h"
27 +#ifndef SHA1DC_NO_STANDARD_INCLUDES
28 +#include <stdint.h>
29 +#endif
30 +#ifdef SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C
31 +#include SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C
32 +#endif
33 +#include "ubc_check.h"
34
35 static const uint32_t DV_I_43_0_bit = (uint32_t)(1) << 0;
36 static const uint32_t DV_I_44_0_bit = (uint32_t)(1) << 1;
@@ -361,3 +366,7 @@ if (mask) {
366
367 dvmask[0]=mask;
368 }
369 +
370 +#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_C
371 +#include SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_C
372 +#endif
sha1dc/ubc_check.h
+11 -3
@@ -20,13 +20,17 @@
20 // thus one needs to do the recompression check for each DV that has its bit set
21 */
22
23 -#ifndef UBC_CHECK_H
24 -#define UBC_CHECK_H
23 +#ifndef SHA1DC_UBC_CHECK_H
24 +#define SHA1DC_UBC_CHECK_H
25
26 #if defined(__cplusplus)
27 extern "C" {
28 #endif
29
30 +#ifndef SHA1DC_NO_STANDARD_INCLUDES
31 +#include <stdint.h>
32 +#endif
33 +
34 #define DVMASKSIZE 1
35 typedef struct { int dvType; int dvK; int dvB; int testt; int maski; int maskb; uint32_t dm[80]; } dv_info_t;
36 extern dv_info_t sha1_dvs[];
@@ -41,4 +45,8 @@ void ubc_check(const uint32_t W[80], uint32_t dvmask[DVMASKSIZE]);
45 }
46 #endif
47
44 -#endif /* UBC_CHECK_H */
48 +#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_H
49 +#include SHA1DC_CUSTOM_TRAILING_INCLUDE_UBC_CHECK_H
50 +#endif
51 +
52 +#endif
sha1dc_git.c new
+24
@@ -0,0 +1,24 @@
1 +/*
2 + * This code is included at the end of sha1dc/sha1.c with the
3 + * SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_C macro.
4 + */
5 +
6 +void git_SHA1DCFinal(unsigned char hash[20], SHA1_CTX *ctx)
7 +{
8 + if (!SHA1DCFinal(hash, ctx))
9 + return;
10 + die("SHA-1 appears to be part of a collision attack: %s",
11 + sha1_to_hex(hash));
12 +}
13 +
14 +void git_SHA1DCUpdate(SHA1_CTX *ctx, const void *vdata, unsigned long len)
15 +{
16 + const char *data = vdata;
17 + /* We expect an unsigned long, but sha1dc only takes an int */
18 + while (len > INT_MAX) {
19 + SHA1DCUpdate(ctx, data, INT_MAX);
20 + data += INT_MAX;
21 + len -= INT_MAX;
22 + }
23 + SHA1DCUpdate(ctx, data, len);
24 +}
sha1dc_git.h new
+19
@@ -0,0 +1,19 @@
1 +/*
2 + * This code is included at the end of sha1dc/sha1.h with the
3 + * SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H macro.
4 + */
5 +
6 +/*
7 + * Same as SHA1DCFinal, but convert collision attack case into a verbose die().
8 + */
9 +void git_SHA1DCFinal(unsigned char [20], SHA1_CTX *);
10 +
11 +/*
12 + * Same as SHA1DCUpdate, but adjust types to match git's usual interface.
13 + */
14 +void git_SHA1DCUpdate(SHA1_CTX *ctx, const void *data, unsigned long len);
15 +
16 +#define platform_SHA_CTX SHA1_CTX
17 +#define platform_SHA1_Init SHA1DCInit
18 +#define platform_SHA1_Update git_SHA1DCUpdate
19 +#define platform_SHA1_Final git_SHA1DCFinal