Rizin
unix-like reverse engineering framework and cli tools
sha256.c
Go to the documentation of this file.
1 //
9 //
10 // This code is based on the code found from 7-Zip, which has a modified
11 // version of the SHA-256 found from Crypto++ <http://www.cryptopp.com/>.
12 // The code was modified a little to fit into liblzma.
13 //
14 // Authors: Kevin Springle
15 // Wei Dai
16 // Igor Pavlov
17 // Lasse Collin
18 //
19 // This file has been put into the public domain.
20 // You can do whatever you want with this file.
21 //
23 
24 #include "check.h"
25 
26 // Rotate a uint32_t. GCC can optimize this to a rotate instruction
27 // at least on x86.
28 static inline uint32_t
29 rotr_32(uint32_t num, unsigned amount)
30 {
31  return (num >> amount) | (num << (32 - amount));
32 }
33 
34 #define blk0(i) (W[i] = conv32be(data[i]))
35 #define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] \
36  + s0(W[(i - 15) & 15]))
37 
38 #define Ch(x, y, z) (z ^ (x & (y ^ z)))
39 #define Maj(x, y, z) ((x & (y ^ z)) + (y & z))
40 
41 #define a(i) T[(0 - i) & 7]
42 #define b(i) T[(1 - i) & 7]
43 #define c(i) T[(2 - i) & 7]
44 #define d(i) T[(3 - i) & 7]
45 #define e(i) T[(4 - i) & 7]
46 #define f(i) T[(5 - i) & 7]
47 #define g(i) T[(6 - i) & 7]
48 #define h(i) T[(7 - i) & 7]
49 
50 #define R(i, j, blk) \
51  h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + SHA256_K[i + j] + blk; \
52  d(i) += h(i); \
53  h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
54 #define R0(i) R(i, 0, blk0(i))
55 #define R2(i) R(i, j, blk2(i))
56 
57 #define S0(x) rotr_32(x ^ rotr_32(x ^ rotr_32(x, 9), 11), 2)
58 #define S1(x) rotr_32(x ^ rotr_32(x ^ rotr_32(x, 14), 5), 6)
59 #define s0(x) (rotr_32(x ^ rotr_32(x, 11), 7) ^ (x >> 3))
60 #define s1(x) (rotr_32(x ^ rotr_32(x, 2), 17) ^ (x >> 10))
61 
62 
63 static const uint32_t SHA256_K[64] = {
64  0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
65  0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
66  0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
67  0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
68  0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
69  0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
70  0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
71  0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
72  0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
73  0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
74  0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
75  0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
76  0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
77  0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
78  0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
79  0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
80 };
81 
82 
83 static void
84 transform(uint32_t state[8], const uint32_t data[16])
85 {
86  uint32_t W[16];
87  uint32_t T[8];
88 
89  // Copy state[] to working vars.
90  memcpy(T, state, sizeof(T));
91 
92  // The first 16 operations unrolled
93  R0( 0); R0( 1); R0( 2); R0( 3);
94  R0( 4); R0( 5); R0( 6); R0( 7);
95  R0( 8); R0( 9); R0(10); R0(11);
96  R0(12); R0(13); R0(14); R0(15);
97 
98  // The remaining 48 operations partially unrolled
99  for (unsigned int j = 16; j < 64; j += 16) {
100  R2( 0); R2( 1); R2( 2); R2( 3);
101  R2( 4); R2( 5); R2( 6); R2( 7);
102  R2( 8); R2( 9); R2(10); R2(11);
103  R2(12); R2(13); R2(14); R2(15);
104  }
105 
106  // Add the working vars back into state[].
107  state[0] += a(0);
108  state[1] += b(0);
109  state[2] += c(0);
110  state[3] += d(0);
111  state[4] += e(0);
112  state[5] += f(0);
113  state[6] += g(0);
114  state[7] += h(0);
115 }
116 
117 
118 static void
120 {
121  transform(check->state.sha256.state, check->buffer.u32);
122  return;
123 }
124 
125 
126 extern void
128 {
129  static const uint32_t s[8] = {
130  0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
131  0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,
132  };
133 
134  memcpy(check->state.sha256.state, s, sizeof(s));
135  check->state.sha256.size = 0;
136 
137  return;
138 }
139 
140 
141 extern void
143 {
144  // Copy the input data into a properly aligned temporary buffer.
145  // This way we can be called with arbitrarily sized buffers
146  // (no need to be multiple of 64 bytes), and the code works also
147  // on architectures that don't allow unaligned memory access.
148  while (size > 0) {
149  const size_t copy_start = check->state.sha256.size & 0x3F;
150  size_t copy_size = 64 - copy_start;
151  if (copy_size > size)
152  copy_size = size;
153 
154  memcpy(check->buffer.u8 + copy_start, buf, copy_size);
155 
156  buf += copy_size;
157  size -= copy_size;
158  check->state.sha256.size += copy_size;
159 
160  if ((check->state.sha256.size & 0x3F) == 0)
161  process(check);
162  }
163 
164  return;
165 }
166 
167 
168 extern void
170 {
171  // Add padding as described in RFC 3174 (it describes SHA-1 but
172  // the same padding style is used for SHA-256 too).
173  size_t pos = check->state.sha256.size & 0x3F;
174  check->buffer.u8[pos++] = 0x80;
175 
176  while (pos != 64 - 8) {
177  if (pos == 64) {
178  process(check);
179  pos = 0;
180  }
181 
182  check->buffer.u8[pos++] = 0x00;
183  }
184 
185  // Convert the message size from bytes to bits.
186  check->state.sha256.size *= 8;
187 
188  check->buffer.u64[(64 - 8) / 8] = conv64be(check->state.sha256.size);
189 
190  process(check);
191 
192  for (size_t i = 0; i < 8; ++i)
193  check->buffer.u32[i] = conv32be(check->state.sha256.state[i]);
194 
195  return;
196 }
#define T(op)
lzma_index ** i
Definition: index.h:629
#define W(x, y, z)
Internal API to different integrity check functions.
lzma_check check
Definition: container.h:292
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
static RzSocket * s
Definition: rtr.c:28
unsigned int uint32_t
Definition: sftypes.h:29
unsigned char uint8_t
Definition: sftypes.h:31
static void transform(uint32_t state[8], const uint32_t data[16])
Definition: sha256.c:84
static void process(lzma_check_state *check)
Definition: sha256.c:119
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
void lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
Update the SHA-256 hash state.
Definition: sha256.c:142
#define f(i)
Definition: sha256.c:46
static uint32_t rotr_32(uint32_t num, unsigned amount)
Definition: sha256.c:29
void lzma_sha256_init(lzma_check_state *check)
Prepare SHA-256 state for new input.
Definition: sha256.c:127
#define c(i)
Definition: sha256.c:43
#define R0(i)
Definition: sha256.c:54
#define R2(i)
Definition: sha256.c:55
#define g(i)
Definition: sha256.c:47
void lzma_sha256_finish(lzma_check_state *check)
Finish the SHA-256 calculation and store the result to check->buffer.u8.
Definition: sha256.c:169
#define a(i)
Definition: sha256.c:41
static const uint32_t SHA256_K[64]
Definition: sha256.c:63
#define h(i)
Definition: sha256.c:48
#define e(i)
Definition: sha256.c:45
Structure to hold internal state of the check being calculated.
Definition: check.h:81
Definition: dis.h:43
int pos
Definition: main.c:11
#define conv32be(num)
#define conv64be(num)