Skip to content
This repository was archived by the owner on Nov 15, 2024. It is now read-only.

Commit a010391

Browse files
avargitster
authored andcommitted
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 28dc98e ("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. cr-marcstevens/sha1collisiondetection@cc46554 2. cr-marcstevens/sha1collisiondetection@33a694a 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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b06d364 commit a010391

File tree

7 files changed

+172
-88
lines changed

7 files changed

+172
-88
lines changed

Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,14 @@ else
14141414
DC_SHA1 := YesPlease
14151415
LIB_OBJS += sha1dc/sha1.o
14161416
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\""
14181425
endif
14191426
endif
14201427
endif

sha1dc/sha1.c

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,23 @@
55
* https://opensource.org/licenses/MIT
66
***/
77

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"
1125

1226

1327
/*
@@ -18,16 +32,31 @@
1832
If you are compiling on a big endian platform and your compiler does not define one of these,
1933
you will have to add whatever macros your tool chain defines to indicate Big-Endianness.
2034
*/
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)) || \
2240
(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
2545

26-
#define SHA1DC_BIGENDIAN 1
27-
#else
28-
#undef SHA1DC_BIGENDIAN
2946
#endif /*ENDIANNESS SELECTION*/
3047

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+
3160
#define rotate_right(x,n) (((x)>>(n))|((x)<<(32-(n))))
3261
#define rotate_left(x,n) (((x)<<(n))|((x)>>(32-(n))))
3362

@@ -36,11 +65,11 @@
3665

3766
#define sha1_mix(W, t) (rotate_left(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1))
3867

39-
#if defined(SHA1DC_BIGENDIAN)
68+
#ifdef SHA1DC_BIGENDIAN
4069
#define sha1_load(m, t, temp) { temp = m[t]; }
4170
#else
4271
#define sha1_load(m, t, temp) { temp = m[t]; sha1_bswap32(temp); }
43-
#endif /* !defined(SHA1DC_BIGENDIAN) */
72+
#endif
4473

4574
#define sha1_store(W, t, x) *(volatile uint32_t *)&W[t] = x
4675

@@ -869,6 +898,11 @@ static void sha1recompress_fast_ ## t (uint32_t ihvin[5], uint32_t ihvout[5], co
869898
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; \
870899
}
871900

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+
872906
#ifdef DOSTORESTATE0
873907
SHA1_RECOMPRESS(0)
874908
#endif
@@ -1189,6 +1223,10 @@ SHA1_RECOMPRESS(78)
11891223
SHA1_RECOMPRESS(79)
11901224
#endif
11911225

1226+
#ifdef _MSC_VER
1227+
#pragma warning(pop)
1228+
#endif
1229+
11921230
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])
11931231
{
11941232
switch (step)
@@ -1662,7 +1700,7 @@ void SHA1DCInit(SHA1_CTX* ctx)
16621700
ctx->ihv[3] = 0x10325476;
16631701
ctx->ihv[4] = 0xC3D2E1F0;
16641702
ctx->found_collision = 0;
1665-
ctx->safe_hash = 0;
1703+
ctx->safe_hash = SHA1DC_INIT_SAFE_HASH_DEFAULT;
16661704
ctx->ubc_check = 1;
16671705
ctx->detect_coll = 1;
16681706
ctx->reduced_round_coll = 0;
@@ -1710,6 +1748,7 @@ void SHA1DCSetCallback(SHA1_CTX* ctx, collision_block_callback callback)
17101748
void SHA1DCUpdate(SHA1_CTX* ctx, const char* buf, size_t len)
17111749
{
17121750
unsigned left, fill;
1751+
17131752
if (len == 0)
17141753
return;
17151754

@@ -1728,7 +1767,13 @@ void SHA1DCUpdate(SHA1_CTX* ctx, const char* buf, size_t len)
17281767
while (len >= 64)
17291768
{
17301769
ctx->total += 64;
1770+
1771+
#if defined(SHA1DC_ALLOW_UNALIGNED_ACCESS)
17311772
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) */
17321777
buf += 64;
17331778
len -= 64;
17341779
}
@@ -1788,22 +1833,6 @@ int SHA1DCFinal(unsigned char output[20], SHA1_CTX *ctx)
17881833
return ctx->found_collision;
17891834
}
17901835

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

Lines changed: 39 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,38 @@
44
* See accompanying file LICENSE.txt or copy at
55
* https://opensource.org/licenses/MIT
66
***/
7+
78
#ifndef SHA1DC_SHA1_H
89
#define SHA1DC_SHA1_H
910

1011
#if defined(__cplusplus)
1112
extern "C" {
1213
#endif
1314

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
2018

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 */
2220
/* only stores states ii (the state between step ii-1 and step ii) when DOSTORESTATEii is defined in ubc_check.h */
2321
void sha1_compression_states(uint32_t[5], const uint32_t[16], uint32_t[80], uint32_t[80][5]);
2422

2523
/*
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.
3331
*/
3432
typedef void(*sha1_recompression_type)(uint32_t*, uint32_t*, const uint32_t*, const uint32_t*);
3533

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: */
4035
/* 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]) */
4136
typedef void(*collision_block_callback)(uint64_t, const uint32_t*, const uint32_t*, const uint32_t*, const uint32_t*);
4237

43-
/* the SHA-1 context */
38+
/* The SHA-1 context. */
4439
typedef struct {
4540
uint64_t total;
4641
uint32_t ihv[5];
@@ -59,30 +54,34 @@ typedef struct {
5954
uint32_t states[80][5];
6055
} SHA1_CTX;
6156

62-
/* initialize SHA-1 context */
57+
/* Initialize SHA-1 context. */
6358
void SHA1DCInit(SHA1_CTX*);
6459

6560
/*
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.
7772
*/
7873
void SHA1DCSetSafeHash(SHA1_CTX*, int);
7974

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+
*/
8279
void SHA1DCSetUseUBC(SHA1_CTX*, int);
8380

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+
*/
8685
void SHA1DCSetUseDetectColl(SHA1_CTX*, int);
8786

8887
/* 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);
10099
/* returns: 0 = no collision detected, otherwise = collision found => warn user for active attack */
101100
int SHA1DCFinal(unsigned char[20], SHA1_CTX*);
102101

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-
118102
#if defined(__cplusplus)
119103
}
120104
#endif
121105

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@
2424
// ubc_check has been verified against ubc_check_verify using the 'ubc_check_test' program in the tools section
2525
*/
2626

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"
2934

3035
static const uint32_t DV_I_43_0_bit = (uint32_t)(1) << 0;
3136
static const uint32_t DV_I_44_0_bit = (uint32_t)(1) << 1;
@@ -361,3 +366,7 @@ if (mask) {
361366

362367
dvmask[0]=mask;
363368
}
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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,17 @@
2020
// thus one needs to do the recompression check for each DV that has its bit set
2121
*/
2222

23-
#ifndef UBC_CHECK_H
24-
#define UBC_CHECK_H
23+
#ifndef SHA1DC_UBC_CHECK_H
24+
#define SHA1DC_UBC_CHECK_H
2525

2626
#if defined(__cplusplus)
2727
extern "C" {
2828
#endif
2929

30+
#ifndef SHA1DC_NO_STANDARD_INCLUDES
31+
#include <stdint.h>
32+
#endif
33+
3034
#define DVMASKSIZE 1
3135
typedef struct { int dvType; int dvK; int dvB; int testt; int maski; int maskb; uint32_t dm[80]; } dv_info_t;
3236
extern dv_info_t sha1_dvs[];
@@ -41,4 +45,8 @@ void ubc_check(const uint32_t W[80], uint32_t dvmask[DVMASKSIZE]);
4145
}
4246
#endif
4347

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

0 commit comments

Comments
 (0)