Skip to content

Commit 63d86c2

Browse files
committed
sha1dc: update to fix errors with endianess and unaligned access
This updates our version of SHA1DC to e139984 (Merge pull request libgit2#35 from lidl/master, 2017-05-30).
1 parent 6a13cf1 commit 63d86c2

File tree

4 files changed

+136
-52
lines changed

4 files changed

+136
-52
lines changed

src/hash/sha1dc/sha1.c

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

8+
#ifndef SHA1DC_NO_STANDARD_INCLUDES
89
#include <string.h>
910
#include <memory.h>
1011
#include <stdio.h>
1112
#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
1222

1323
#include "sha1.h"
1424
#include "ubc_check.h"
1525

1626

17-
/*
27+
/*
1828
Because Little-Endian architectures are most common,
19-
we only set BIGENDIAN if one of these conditions is met.
29+
we only set SHA1DC_BIGENDIAN if one of these conditions is met.
2030
Note that all MSFT platforms are little endian,
2131
so none of these will be defined under the MSC compiler.
2232
If you are compiling on a big endian platform and your compiler does not define one of these,
2333
you will have to add whatever macros your tool chain defines to indicate Big-Endianness.
2434
*/
25-
#if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || \
26-
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)) || \
27-
defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
28-
defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__)
35+
#ifdef SHA1DC_BIGENDIAN
36+
#undef SHA1DC_BIGENDIAN
37+
#endif
38+
39+
#if (defined(_BYTE_ORDER) || defined(__BYTE_ORDER) || defined(__BYTE_ORDER__))
40+
41+
#if ((defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)) || \
42+
(defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || \
43+
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)) )
44+
#define SHA1DC_BIGENDIAN
45+
#endif
46+
47+
#else
48+
49+
#if (defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN) || defined(__BIG_ENDIAN__) || \
50+
defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
51+
defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || \
52+
defined(__sparc))
53+
#define SHA1DC_BIGENDIAN
54+
#endif
55+
56+
#endif
57+
58+
#if (defined(SHA1DC_FORCE_LITTLEENDIAN) && defined(SHA1DC_BIGENDIAN))
59+
#undef SHA1DC_BIGENDIAN
60+
#endif
61+
#if (defined(SHA1DC_FORCE_BIGENDIAN) && !defined(SHA1DC_BIGENDIAN))
62+
#define SHA1DC_BIGENDIAN
63+
#endif
64+
/*ENDIANNESS SELECTION*/
65+
66+
#if (defined SHA1DC_FORCE_UNALIGNED_ACCESS || \
67+
defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
68+
defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || \
69+
defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || \
70+
defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || \
71+
defined(__386) || defined(_M_X64) || defined(_M_AMD64))
72+
73+
#define SHA1DC_ALLOW_UNALIGNED_ACCESS
2974

30-
#define BIGENDIAN (1)
75+
#endif /*UNALIGNMENT DETECTION*/
3176

32-
#endif /*ENDIANNESS SELECTION*/
3377

3478
#define rotate_right(x,n) (((x)>>(n))|((x)<<(32-(n))))
3579
#define rotate_left(x,n) (((x)<<(n))|((x)>>(32-(n))))
@@ -39,11 +83,11 @@
3983

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

42-
#if defined(BIGENDIAN)
86+
#ifdef SHA1DC_BIGENDIAN
4387
#define sha1_load(m, t, temp) { temp = m[t]; }
4488
#else
4589
#define sha1_load(m, t, temp) { temp = m[t]; sha1_bswap32(temp); }
46-
#endif /*define(BIGENDIAN)*/
90+
#endif
4791

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

@@ -872,6 +916,11 @@ static void sha1recompress_fast_ ## t (uint32_t ihvin[5], uint32_t ihvout[5], co
872916
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; \
873917
}
874918

919+
#ifdef _MSC_VER
920+
#pragma warning(push)
921+
#pragma warning(disable: 4127) /* Complier complains about the checks in the above macro being constant. */
922+
#endif
923+
875924
#ifdef DOSTORESTATE0
876925
SHA1_RECOMPRESS(0)
877926
#endif
@@ -1192,6 +1241,10 @@ SHA1_RECOMPRESS(78)
11921241
SHA1_RECOMPRESS(79)
11931242
#endif
11941243

1244+
#ifdef _MSC_VER
1245+
#pragma warning(pop)
1246+
#endif
1247+
11951248
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])
11961249
{
11971250
switch (step)
@@ -1609,7 +1662,7 @@ static void sha1_process(SHA1_CTX* ctx, const uint32_t block[16])
16091662
unsigned i, j;
16101663
uint32_t ubc_dv_mask[DVMASKSIZE] = { 0xFFFFFFFF };
16111664
uint32_t ihvtmp[5];
1612-
1665+
16131666
ctx->ihv1[0] = ctx->ihv[0];
16141667
ctx->ihv1[1] = ctx->ihv[1];
16151668
ctx->ihv1[2] = ctx->ihv[2];
@@ -1665,7 +1718,7 @@ void SHA1DCInit(SHA1_CTX* ctx)
16651718
ctx->ihv[3] = 0x10325476;
16661719
ctx->ihv[4] = 0xC3D2E1F0;
16671720
ctx->found_collision = 0;
1668-
ctx->safe_hash = 1;
1721+
ctx->safe_hash = SHA1DC_INIT_SAFE_HASH_DEFAULT;
16691722
ctx->ubc_check = 1;
16701723
ctx->detect_coll = 1;
16711724
ctx->reduced_round_coll = 0;
@@ -1713,6 +1766,7 @@ void SHA1DCSetCallback(SHA1_CTX* ctx, collision_block_callback callback)
17131766
void SHA1DCUpdate(SHA1_CTX* ctx, const char* buf, size_t len)
17141767
{
17151768
unsigned left, fill;
1769+
17161770
if (len == 0)
17171771
return;
17181772

@@ -1731,7 +1785,13 @@ void SHA1DCUpdate(SHA1_CTX* ctx, const char* buf, size_t len)
17311785
while (len >= 64)
17321786
{
17331787
ctx->total += 64;
1788+
1789+
#if defined(SHA1DC_ALLOW_UNALIGNED_ACCESS)
17341790
sha1_process(ctx, (uint32_t*)(buf));
1791+
#else
1792+
memcpy(ctx->buffer, buf, 64);
1793+
sha1_process(ctx, (uint32_t*)(ctx->buffer));
1794+
#endif /* defined(SHA1DC_ALLOW_UNALIGNED_ACCESS) */
17351795
buf += 64;
17361796
len -= 64;
17371797
}
@@ -1790,3 +1850,7 @@ int SHA1DCFinal(unsigned char output[20], SHA1_CTX *ctx)
17901850
output[19] = (unsigned char)(ctx->ihv[4]);
17911851
return ctx->found_collision;
17921852
}
1853+
1854+
#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_C
1855+
#include SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_C
1856+
#endif

src/hash/sha1dc/sha1.h

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

8+
#ifndef SHA1DC_SHA1_H
9+
#define SHA1DC_SHA1_H
10+
811
#if defined(__cplusplus)
912
extern "C" {
1013
#endif
1114

15+
#ifndef SHA1DC_NO_STANDARD_INCLUDES
1216
#include <stdint.h>
17+
#endif
1318

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]); */
20-
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 */
@@ -98,8 +97,14 @@ void SHA1DCUpdate(SHA1_CTX*, const char*, size_t);
9897

9998
/* obtain SHA-1 hash from SHA-1 context */
10099
/* returns: 0 = no collision detected, otherwise = collision found => warn user for active attack */
101-
int SHA1DCFinal(unsigned char[20], SHA1_CTX*);
100+
int SHA1DCFinal(unsigned char[20], SHA1_CTX*);
102101

103102
#if defined(__cplusplus)
104103
}
105104
#endif
105+
106+
#ifdef SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H
107+
#include SHA1DC_CUSTOM_TRAILING_INCLUDE_SHA1_H
108+
#endif
109+
110+
#endif

src/hash/sha1dc/ubc_check.c

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

27+
#ifndef SHA1DC_NO_STANDARD_INCLUDES
2728
#include <stdint.h>
29+
#endif
30+
#ifdef SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C
31+
#include SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C
32+
#endif
2833
#include "ubc_check.h"
2934

3035
static const uint32_t DV_I_43_0_bit = (uint32_t)(1) << 0;
@@ -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

src/hash/sha1dc/ubc_check.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@
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
3031
#include <stdint.h>
32+
#endif
3133

3234
#define DVMASKSIZE 1
3335
typedef struct { int dvType; int dvK; int dvB; int testt; int maski; int maskb; uint32_t dm[80]; } dv_info_t;
@@ -43,4 +45,8 @@ void ubc_check(const uint32_t W[80], uint32_t dvmask[DVMASKSIZE]);
4345
}
4446
#endif
4547

46-
#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

0 commit comments

Comments
 (0)