Minetest  5.4.0
md32_common.h
Go to the documentation of this file.
1 /* md32_common.h file used by sha256 implementation */
2 /* ====================================================================
3  * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in
14  * the documentation and/or other materials provided with the
15  * distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this
18  * software must display the following acknowledgment:
19  * "This product includes software developed by the OpenSSL Project
20  * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21  *
22  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23  * endorse or promote products derived from this software without
24  * prior written permission. For written permission, please contact
25  * licensing@OpenSSL.org.
26  *
27  * 5. Products derived from this software may not be called "OpenSSL"
28  * nor may "OpenSSL" appear in their names without prior written
29  * permission of the OpenSSL Project.
30  *
31  * 6. Redistributions of any form whatsoever must retain the following
32  * acknowledgment:
33  * "This product includes software developed by the OpenSSL Project
34  * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47  * OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  */
51 
52 /*-
53  * This is a generic 32 bit "collector" for message digest algorithms.
54  * Whenever needed it collects input character stream into chunks of
55  * 32 bit values and invokes a block function that performs actual hash
56  * calculations.
57  *
58  * Porting guide.
59  *
60  * Obligatory macros:
61  *
62  * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
63  * this macro defines byte order of input stream.
64  * HASH_CBLOCK
65  * size of a unit chunk HASH_BLOCK operates on.
66  * HASH_LONG
67  * has to be at lest 32 bit wide, if it's wider, then
68  * HASH_LONG_LOG2 *has to* be defined along
69  * HASH_CTX
70  * context structure that at least contains following
71  * members:
72  * typedef struct {
73  * ...
74  * HASH_LONG Nl,Nh;
75  * either {
76  * HASH_LONG data[HASH_LBLOCK];
77  * unsigned char data[HASH_CBLOCK];
78  * };
79  * unsigned int num;
80  * ...
81  * } HASH_CTX;
82  * data[] vector is expected to be zeroed upon first call to
83  * HASH_UPDATE.
84  * HASH_UPDATE
85  * name of "Update" function, implemented here.
86  * HASH_TRANSFORM
87  * name of "Transform" function, implemented here.
88  * HASH_FINAL
89  * name of "Final" function, implemented here.
90  * HASH_BLOCK_DATA_ORDER
91  * name of "block" function capable of treating *unaligned* input
92  * message in original (data) byte order, implemented externally.
93  * HASH_MAKE_STRING
94  * macro convering context variables to an ASCII hash string.
95  *
96  * MD5 example:
97  *
98  * #define DATA_ORDER_IS_LITTLE_ENDIAN
99  *
100  * #define HASH_LONG MD5_LONG
101  * #define HASH_LONG_LOG2 MD5_LONG_LOG2
102  * #define HASH_CTX MD5_CTX
103  * #define HASH_CBLOCK MD5_CBLOCK
104  * #define HASH_UPDATE MD5_Update
105  * #define HASH_TRANSFORM MD5_Transform
106  * #define HASH_FINAL MD5_Final
107  * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
108  *
109  * <appro@fy.chalmers.se>
110  */
111 
112 #pragma once
113 
114 #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
115 # error "DATA_ORDER must be defined!"
116 #endif
117 
118 #ifndef HASH_CBLOCK
119 # error "HASH_CBLOCK must be defined!"
120 #endif
121 #ifndef HASH_LONG
122 # error "HASH_LONG must be defined!"
123 #endif
124 #ifndef HASH_CTX
125 # error "HASH_CTX must be defined!"
126 #endif
127 
128 #ifndef HASH_UPDATE
129 # error "HASH_UPDATE must be defined!"
130 #endif
131 #ifndef HASH_TRANSFORM
132 # error "HASH_TRANSFORM must be defined!"
133 #endif
134 #ifndef HASH_FINAL
135 # error "HASH_FINAL must be defined!"
136 #endif
137 
138 #ifndef HASH_BLOCK_DATA_ORDER
139 # error "HASH_BLOCK_DATA_ORDER must be defined!"
140 #endif
141 
142 /*
143  * Engage compiler specific rotate intrinsic function if available.
144  */
145 #undef ROTATE
146 #ifndef PEDANTIC
147 # if defined(_MSC_VER)
148 # define ROTATE(a,n) _lrotl(a,n)
149 # elif defined(__ICC)
150 # define ROTATE(a,n) _rotl(a,n)
151 # elif defined(__MWERKS__)
152 # if defined(__POWERPC__)
153 # define ROTATE(a,n) __rlwinm(a,n,0,31)
154 # elif defined(__MC68K__)
155  /* Motorola specific tweak. <appro@fy.chalmers.se> */
156 # define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
157 # else
158 # define ROTATE(a,n) __rol(a,n)
159 # endif
160 # elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
161  /*
162  * Some GNU C inline assembler templates. Note that these are
163  * rotates by *constant* number of bits! But that's exactly
164  * what we need here...
165  * <appro@fy.chalmers.se>
166  */
167 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
168 # define ROTATE(a,n) ({ register unsigned int ret; \
169  asm ( \
170  "roll %1,%0" \
171  : "=r"(ret) \
172  : "I"(n), "0"((unsigned int)(a)) \
173  : "cc"); \
174  ret; \
175  })
176 # elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
177  defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
178 # define ROTATE(a,n) ({ register unsigned int ret; \
179  asm ( \
180  "rlwinm %0,%1,%2,0,31" \
181  : "=r"(ret) \
182  : "r"(a), "I"(n)); \
183  ret; \
184  })
185 # elif defined(__s390x__)
186 # define ROTATE(a,n) ({ register unsigned int ret; \
187  asm ("rll %0,%1,%2" \
188  : "=r"(ret) \
189  : "r"(a), "I"(n)); \
190  ret; \
191  })
192 # endif
193 # endif
194 #endif /* PEDANTIC */
195 
196 #ifndef ROTATE
197 # define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
198 #endif
199 
200 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
201 
202 # ifndef PEDANTIC
203 # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
204 # if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
205  (defined(__x86_64) || defined(__x86_64__))
206 # if !defined(B_ENDIAN)
207  /*
208  * This gives ~30-40% performance improvement in SHA-256 compiled
209  * with gcc [on P4]. Well, first macro to be frank. We can pull
210  * this trick on x86* platforms only, because these CPUs can fetch
211  * unaligned data without raising an exception.
212  */
213 # define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \
214  asm ("bswapl %0":"=r"(r):"0"(r)); \
215  (c)+=4; (l)=r; })
216 # define HOST_l2c(l,c) ({ unsigned int r=(l); \
217  asm ("bswapl %0":"=r"(r):"0"(r)); \
218  *((unsigned int *)(c))=r; (c)+=4; r; })
219 # endif
220 # elif defined(__aarch64__)
221 # if defined(__BYTE_ORDER__)
222 # if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
223 # define HOST_c2l(c,l) ({ unsigned int r; \
224  asm ("rev %w0,%w1" \
225  :"=r"(r) \
226  :"r"(*((const unsigned int *)(c))));\
227  (c)+=4; (l)=r; })
228 # define HOST_l2c(l,c) ({ unsigned int r; \
229  asm ("rev %w0,%w1" \
230  :"=r"(r) \
231  :"r"((unsigned int)(l)));\
232  *((unsigned int *)(c))=r; (c)+=4; r; })
233 # elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
234 # define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
235 # define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
236 # endif
237 # endif
238 # endif
239 # endif
240 # if defined(__s390__) || defined(__s390x__)
241 # define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
242 # define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
243 # endif
244 # endif
245 
246 # ifndef HOST_c2l
247 # define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
248  l|=(((unsigned long)(*((c)++)))<<16), \
249  l|=(((unsigned long)(*((c)++)))<< 8), \
250  l|=(((unsigned long)(*((c)++))) ) )
251 # endif
252 # ifndef HOST_l2c
253 # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
254  *((c)++)=(unsigned char)(((l)>>16)&0xff), \
255  *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
256  *((c)++)=(unsigned char)(((l) )&0xff), \
257  l)
258 # endif
259 
260 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
261 
262 # ifndef PEDANTIC
263 # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
264 # if defined(__s390x__)
265 # define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \
266  :"=d"(l) :"m"(*(const unsigned int *)(c)));\
267  (c)+=4; (l); })
268 # define HOST_l2c(l,c) ({ asm ("strv %1,%0" \
269  :"=m"(*(unsigned int *)(c)) :"d"(l));\
270  (c)+=4; (l); })
271 # endif
272 # endif
273 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
274 # ifndef B_ENDIAN
275  /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
276 # define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l)
277 # define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l)
278 # endif
279 # endif
280 # endif
281 
282 # ifndef HOST_c2l
283 # define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
284  l|=(((unsigned long)(*((c)++)))<< 8), \
285  l|=(((unsigned long)(*((c)++)))<<16), \
286  l|=(((unsigned long)(*((c)++)))<<24) )
287 # endif
288 # ifndef HOST_l2c
289 # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
290  *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
291  *((c)++)=(unsigned char)(((l)>>16)&0xff), \
292  *((c)++)=(unsigned char)(((l)>>24)&0xff), \
293  l)
294 # endif
295 
296 #endif
297 
298 /*
299  * Time for some action:-)
300  */
301 
302 int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
303 {
304  const unsigned char *data = (const unsigned char *)data_;
305  unsigned char *p;
306  HASH_LONG l;
307  size_t n;
308 
309  if (len == 0)
310  return 1;
311 
312  l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
313  /*
314  * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
315  * <weidai@eskimo.com> for pointing it out.
316  */
317  if (l < c->Nl) /* overflow */
318  c->Nh++;
319  c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
320  * 16-bit */
321  c->Nl = l;
322 
323  n = c->num;
324  if (n != 0) {
325  p = (unsigned char *)c->data;
326 
327  if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
328  memcpy(p + n, data, HASH_CBLOCK - n);
329  HASH_BLOCK_DATA_ORDER(c, p, 1);
330  n = HASH_CBLOCK - n;
331  data += n;
332  len -= n;
333  c->num = 0;
334  memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
335  } else {
336  memcpy(p + n, data, len);
337  c->num += (unsigned int)len;
338  return 1;
339  }
340  }
341 
342  n = len / HASH_CBLOCK;
343  if (n > 0) {
344  HASH_BLOCK_DATA_ORDER(c, data, n);
345  n *= HASH_CBLOCK;
346  data += n;
347  len -= n;
348  }
349 
350  if (len != 0) {
351  p = (unsigned char *)c->data;
352  c->num = (unsigned int)len;
353  memcpy(p, data, len);
354  }
355  return 1;
356 }
357 
358 void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
359 {
360  HASH_BLOCK_DATA_ORDER(c, data, 1);
361 }
362 
363 int HASH_FINAL(unsigned char *md, HASH_CTX *c)
364 {
365  unsigned char *p = (unsigned char *)c->data;
366  size_t n = c->num;
367 
368  p[n] = 0x80; /* there is always room for one */
369  n++;
370 
371  if (n > (HASH_CBLOCK - 8)) {
372  memset(p + n, 0, HASH_CBLOCK - n);
373  n = 0;
374  HASH_BLOCK_DATA_ORDER(c, p, 1);
375  }
376  memset(p + n, 0, HASH_CBLOCK - 8 - n);
377 
378  p += HASH_CBLOCK - 8;
379 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
380  (void)HOST_l2c(c->Nh, p);
381  (void)HOST_l2c(c->Nl, p);
382 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
383  (void)HOST_l2c(c->Nl, p);
384  (void)HOST_l2c(c->Nh, p);
385 #endif
386  p -= HASH_CBLOCK;
387  HASH_BLOCK_DATA_ORDER(c, p, 1);
388  c->num = 0;
389  memset(p, 0, HASH_CBLOCK);
390 
391 #ifndef HASH_MAKE_STRING
392 # error "HASH_MAKE_STRING must be defined!"
393 #else
394  HASH_MAKE_STRING(c, md);
395 #endif
396 
397  return 1;
398 }
399 
400 #ifndef MD32_REG_T
401 # if defined(__alpha) || defined(__sparcv9) || defined(__mips)
402 # define MD32_REG_T long
403 /*
404  * This comment was originaly written for MD5, which is why it
405  * discusses A-D. But it basically applies to all 32-bit digests,
406  * which is why it was moved to common header file.
407  *
408  * In case you wonder why A-D are declared as long and not
409  * as MD5_LONG. Doing so results in slight performance
410  * boost on LP64 architectures. The catch is we don't
411  * really care if 32 MSBs of a 64-bit register get polluted
412  * with eventual overflows as we *save* only 32 LSBs in
413  * *either* case. Now declaring 'em long excuses the compiler
414  * from keeping 32 MSBs zeroed resulting in 13% performance
415  * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
416  * Well, to be honest it should say that this *prevents*
417  * performance degradation.
418  * <appro@fy.chalmers.se>
419  */
420 # else
421 /*
422  * Above is not absolute and there are LP64 compilers that
423  * generate better code if MD32_REG_T is defined int. The above
424  * pre-processor condition reflects the circumstances under which
425  * the conclusion was made and is subject to further extension.
426  * <appro@fy.chalmers.se>
427  */
428 # define MD32_REG_T int
429 # endif
430 #endif
int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
Definition: md32_common.h:302
int HASH_FINAL(unsigned char *md, HASH_CTX *c)
Definition: md32_common.h:363
void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
Definition: md32_common.h:358
#define HASH_BLOCK_DATA_ORDER
Definition: sha256.c:138
#define HASH_CTX
Definition: sha256.c:104
#define HASH_CBLOCK
Definition: sha256.c:105
#define HASH_MAKE_STRING(c, s)
Definition: sha256.c:114
#define HASH_LONG
Definition: sha256.c:103
std::string p(std::string path)
Definition: test_filepath.cpp:59