line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/* algorithms.c - the algorithms supported by the rhash library |
2
|
|
|
|
|
|
|
* |
3
|
|
|
|
|
|
|
* Copyright: 2011-2012 Aleksey Kravchenko |
4
|
|
|
|
|
|
|
* |
5
|
|
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a |
6
|
|
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"), |
7
|
|
|
|
|
|
|
* to deal in the Software without restriction, including without limitation |
8
|
|
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
9
|
|
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the |
10
|
|
|
|
|
|
|
* Software is furnished to do so. |
11
|
|
|
|
|
|
|
* |
12
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful, but |
13
|
|
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
14
|
|
|
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! |
15
|
|
|
|
|
|
|
*/ |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#include |
18
|
|
|
|
|
|
|
#include |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
#include "byte_order.h" |
21
|
|
|
|
|
|
|
#include "rhash.h" |
22
|
|
|
|
|
|
|
#include "algorithms.h" |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
/* header files of all supported hash sums */ |
25
|
|
|
|
|
|
|
#include "aich.h" |
26
|
|
|
|
|
|
|
#include "crc32.h" |
27
|
|
|
|
|
|
|
#include "ed2k.h" |
28
|
|
|
|
|
|
|
#include "edonr.h" |
29
|
|
|
|
|
|
|
#include "gost.h" |
30
|
|
|
|
|
|
|
#include "has160.h" |
31
|
|
|
|
|
|
|
#include "md4.h" |
32
|
|
|
|
|
|
|
#include "md5.h" |
33
|
|
|
|
|
|
|
#include "ripemd-160.h" |
34
|
|
|
|
|
|
|
#include "snefru.h" |
35
|
|
|
|
|
|
|
#include "sha1.h" |
36
|
|
|
|
|
|
|
#include "sha256.h" |
37
|
|
|
|
|
|
|
#include "sha512.h" |
38
|
|
|
|
|
|
|
#include "sha3.h" |
39
|
|
|
|
|
|
|
#include "tiger.h" |
40
|
|
|
|
|
|
|
#include "torrent.h" |
41
|
|
|
|
|
|
|
#include "tth.h" |
42
|
|
|
|
|
|
|
#include "whirlpool.h" |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
#ifdef USE_OPENSSL |
45
|
|
|
|
|
|
|
/* note: BTIH and AICH depends on the used SHA1 algorithm */ |
46
|
|
|
|
|
|
|
# define NEED_OPENSSL_INIT (RHASH_MD4 | RHASH_MD5 | \ |
47
|
|
|
|
|
|
|
RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | \ |
48
|
|
|
|
|
|
|
RHASH_BTIH | RHASH_AICH | RHASH_RIPEMD160 | RHASH_WHIRLPOOL) |
49
|
|
|
|
|
|
|
#else |
50
|
|
|
|
|
|
|
# define NEED_OPENSSL_INIT 0 |
51
|
|
|
|
|
|
|
#endif /* USE_OPENSSL */ |
52
|
|
|
|
|
|
|
#ifdef GENERATE_GOST_LOOKUP_TABLE |
53
|
|
|
|
|
|
|
# define NEED_GOST_INIT (RHASH_GOST | RHASH_GOST_CRYPTOPRO) |
54
|
|
|
|
|
|
|
#else |
55
|
|
|
|
|
|
|
# define NEED_GOST_INIT 0 |
56
|
|
|
|
|
|
|
#endif /* GENERATE_GOST_LOOKUP_TABLE */ |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
#define RHASH_NEED_INIT_ALG (NEED_GOST_INIT | NEED_OPENSSL_INIT) |
59
|
|
|
|
|
|
|
unsigned rhash_uninitialized_algorithms = RHASH_NEED_INIT_ALG; |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
rhash_hash_info* rhash_info_table = rhash_hash_info_default; |
62
|
|
|
|
|
|
|
int rhash_info_size = RHASH_HASH_COUNT; |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
static void rhash_crc32_init(uint32_t* crc32); |
65
|
|
|
|
|
|
|
static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size); |
66
|
|
|
|
|
|
|
static void rhash_crc32_final(uint32_t* crc32, unsigned char* result); |
67
|
|
|
|
|
|
|
static void rhash_crc32c_init(uint32_t* crc32); |
68
|
|
|
|
|
|
|
static void rhash_crc32c_update(uint32_t* crc32, const unsigned char* msg, size_t size); |
69
|
|
|
|
|
|
|
static void rhash_crc32c_final(uint32_t* crc32, unsigned char* result); |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" }; |
72
|
|
|
|
|
|
|
rhash_info info_crc32c = { RHASH_CRC32C, F_BE32, 4, "CRC32C", "crc32c" }; |
73
|
|
|
|
|
|
|
rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" }; |
74
|
|
|
|
|
|
|
rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" }; |
75
|
|
|
|
|
|
|
rhash_info info_sha1 = { RHASH_SHA1, F_BE32, 20, "SHA1", "sha1" }; |
76
|
|
|
|
|
|
|
rhash_info info_tiger = { RHASH_TIGER, F_LE64, 24, "TIGER", "tiger" }; |
77
|
|
|
|
|
|
|
rhash_info info_tth = { RHASH_TTH, F_BS32, 24, "TTH", "tree:tiger" }; |
78
|
|
|
|
|
|
|
rhash_info info_btih = { RHASH_BTIH, 0, 20, "BTIH", "btih" }; |
79
|
|
|
|
|
|
|
rhash_info info_ed2k = { RHASH_ED2K, F_LE32, 16, "ED2K", "ed2k" }; |
80
|
|
|
|
|
|
|
rhash_info info_aich = { RHASH_AICH, F_BS32, 20, "AICH", "aich" }; |
81
|
|
|
|
|
|
|
rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" }; |
82
|
|
|
|
|
|
|
rhash_info info_rmd160 = { RHASH_RIPEMD160, F_LE32, 20, "RIPEMD-160", "ripemd160" }; |
83
|
|
|
|
|
|
|
rhash_info info_gost = { RHASH_GOST, F_LE32, 32, "GOST", "gost" }; |
84
|
|
|
|
|
|
|
rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "GOST-CRYPTOPRO", "gost-cryptopro" }; |
85
|
|
|
|
|
|
|
rhash_info info_has160 = { RHASH_HAS160, F_LE32, 20, "HAS-160", "has160" }; |
86
|
|
|
|
|
|
|
rhash_info info_snf128 = { RHASH_SNEFRU128, F_BE32, 16, "SNEFRU-128", "snefru128" }; |
87
|
|
|
|
|
|
|
rhash_info info_snf256 = { RHASH_SNEFRU256, F_BE32, 32, "SNEFRU-256", "snefru256" }; |
88
|
|
|
|
|
|
|
rhash_info info_sha224 = { RHASH_SHA224, F_BE32, 28, "SHA-224", "sha224" }; |
89
|
|
|
|
|
|
|
rhash_info info_sha256 = { RHASH_SHA256, F_BE32, 32, "SHA-256", "sha256" }; |
90
|
|
|
|
|
|
|
rhash_info info_sha384 = { RHASH_SHA384, F_BE64, 48, "SHA-384", "sha384" }; |
91
|
|
|
|
|
|
|
rhash_info info_sha512 = { RHASH_SHA512, F_BE64, 64, "SHA-512", "sha512" }; |
92
|
|
|
|
|
|
|
rhash_info info_edr256 = { RHASH_EDONR256, F_LE32, 32, "EDON-R256", "edon-r256" }; |
93
|
|
|
|
|
|
|
rhash_info info_edr512 = { RHASH_EDONR512, F_LE64, 64, "EDON-R512", "edon-r512" }; |
94
|
|
|
|
|
|
|
rhash_info info_sha3_224 = { RHASH_SHA3_224, F_LE64, 28, "SHA3-224", "sha3-224" }; |
95
|
|
|
|
|
|
|
rhash_info info_sha3_256 = { RHASH_SHA3_256, F_LE64, 32, "SHA3-256", "sha3-256" }; |
96
|
|
|
|
|
|
|
rhash_info info_sha3_384 = { RHASH_SHA3_384, F_LE64, 48, "SHA3-384", "sha3-384" }; |
97
|
|
|
|
|
|
|
rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512" }; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
/* some helper macros */ |
100
|
|
|
|
|
|
|
#define dgshft(name) (((char*)&((name##_ctx*)0)->hash) - (char*)0) |
101
|
|
|
|
|
|
|
#define dgshft2(name, field) (((char*)&((name##_ctx*)0)->field) - (char*)0) |
102
|
|
|
|
|
|
|
#define ini(name) ((pinit_t)(name##_init)) |
103
|
|
|
|
|
|
|
#define upd(name) ((pupdate_t)(name##_update)) |
104
|
|
|
|
|
|
|
#define fin(name) ((pfinal_t)(name##_final)) |
105
|
|
|
|
|
|
|
#define iuf(name) ini(name), upd(name), fin(name) |
106
|
|
|
|
|
|
|
#define diuf(name) dgshft(name), ini(name), upd(name), fin(name) |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
/* information about all supported hash functions */ |
109
|
|
|
|
|
|
|
rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] = |
110
|
|
|
|
|
|
|
{ |
111
|
|
|
|
|
|
|
{ &info_crc32, sizeof(uint32_t), 0, iuf(rhash_crc32), 0 }, /* 32 bit */ |
112
|
|
|
|
|
|
|
{ &info_md4, sizeof(md4_ctx), dgshft(md4), iuf(rhash_md4), 0 }, /* 128 bit */ |
113
|
|
|
|
|
|
|
{ &info_md5, sizeof(md5_ctx), dgshft(md5), iuf(rhash_md5), 0 }, /* 128 bit */ |
114
|
|
|
|
|
|
|
{ &info_sha1, sizeof(sha1_ctx), dgshft(sha1), iuf(rhash_sha1), 0 }, /* 160 bit */ |
115
|
|
|
|
|
|
|
{ &info_tiger, sizeof(tiger_ctx), dgshft(tiger), iuf(rhash_tiger), 0 }, /* 192 bit */ |
116
|
|
|
|
|
|
|
{ &info_tth, sizeof(tth_ctx), dgshft2(tth, tiger.hash), iuf(rhash_tth), 0 }, /* 192 bit */ |
117
|
|
|
|
|
|
|
{ &info_btih, sizeof(torrent_ctx), dgshft2(torrent, btih), iuf(bt), (pcleanup_t)bt_cleanup }, /* 160 bit */ |
118
|
|
|
|
|
|
|
{ &info_ed2k, sizeof(ed2k_ctx), dgshft2(ed2k, md4_context_inner.hash), iuf(rhash_ed2k), 0 }, /* 128 bit */ |
119
|
|
|
|
|
|
|
{ &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */ |
120
|
|
|
|
|
|
|
{ &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */ |
121
|
|
|
|
|
|
|
{ &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */ |
122
|
|
|
|
|
|
|
{ &info_gost, sizeof(gost_ctx), dgshft(gost), iuf(rhash_gost), 0 }, /* 256 bit */ |
123
|
|
|
|
|
|
|
{ &info_gostpro, sizeof(gost_ctx), dgshft(gost), ini(rhash_gost_cryptopro), upd(rhash_gost), fin(rhash_gost), 0 }, /* 256 bit */ |
124
|
|
|
|
|
|
|
{ &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */ |
125
|
|
|
|
|
|
|
{ &info_snf128, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru128), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 128 bit */ |
126
|
|
|
|
|
|
|
{ &info_snf256, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru256), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 256 bit */ |
127
|
|
|
|
|
|
|
{ &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(rhash_sha256), 0 }, /* 224 bit */ |
128
|
|
|
|
|
|
|
{ &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 }, /* 256 bit */ |
129
|
|
|
|
|
|
|
{ &info_sha384, sizeof(sha512_ctx), dgshft(sha512), ini(rhash_sha384), upd(rhash_sha512), fin(rhash_sha512), 0 }, /* 384 bit */ |
130
|
|
|
|
|
|
|
{ &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 }, /* 512 bit */ |
131
|
|
|
|
|
|
|
{ &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */ |
132
|
|
|
|
|
|
|
{ &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */ |
133
|
|
|
|
|
|
|
{ &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_224), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 224 bit */ |
134
|
|
|
|
|
|
|
{ &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_256), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 256 bit */ |
135
|
|
|
|
|
|
|
{ &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_384), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 384 bit */ |
136
|
|
|
|
|
|
|
{ &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_512), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 512 bit */ |
137
|
|
|
|
|
|
|
{ &info_crc32c, sizeof(uint32_t), 0, iuf(rhash_crc32c), 0 }, /* 32 bit */ |
138
|
|
|
|
|
|
|
}; |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
/** |
141
|
|
|
|
|
|
|
* Initialize requested algorithms. |
142
|
|
|
|
|
|
|
* |
143
|
|
|
|
|
|
|
* @param mask ids of hash sums to initialize |
144
|
|
|
|
|
|
|
*/ |
145
|
3
|
|
|
|
|
|
void rhash_init_algorithms(unsigned mask) |
146
|
|
|
|
|
|
|
{ |
147
|
|
|
|
|
|
|
(void)mask; /* unused now */ |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
/* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */ |
150
|
|
|
|
|
|
|
assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1))); |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
#ifdef GENERATE_GOST_LOOKUP_TABLE |
153
|
|
|
|
|
|
|
rhash_gost_init_table(); |
154
|
|
|
|
|
|
|
#endif |
155
|
3
|
|
|
|
|
|
rhash_uninitialized_algorithms = 0; |
156
|
3
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
/** |
159
|
|
|
|
|
|
|
* Returns information about a hash function by its hash_id. |
160
|
|
|
|
|
|
|
* |
161
|
|
|
|
|
|
|
* @param hash_id the id of hash algorithm |
162
|
|
|
|
|
|
|
* @return pointer to the rhash_info structure containing the information |
163
|
|
|
|
|
|
|
*/ |
164
|
63
|
|
|
|
|
|
const rhash_info* rhash_info_by_id(unsigned hash_id) |
165
|
|
|
|
|
|
|
{ |
166
|
63
|
|
|
|
|
|
hash_id &= RHASH_ALL_HASHES; |
167
|
|
|
|
|
|
|
/* check that only one bit is set */ |
168
|
63
|
50
|
|
|
|
|
if (hash_id != (hash_id & -(int)hash_id)) return NULL; |
169
|
|
|
|
|
|
|
/* note: alternative condition is (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) */ |
170
|
63
|
|
|
|
|
|
return rhash_info_table[rhash_ctz(hash_id)].info; |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
/* CRC32 helper functions */ |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
/** |
176
|
|
|
|
|
|
|
* Initialize crc32 hash. |
177
|
|
|
|
|
|
|
* |
178
|
|
|
|
|
|
|
* @param crc32 pointer to the hash to initialize |
179
|
|
|
|
|
|
|
*/ |
180
|
3
|
|
|
|
|
|
static void rhash_crc32_init(uint32_t* crc32) |
181
|
|
|
|
|
|
|
{ |
182
|
3
|
|
|
|
|
|
*crc32 = 0; /* note: context size is sizeof(uint32_t) */ |
183
|
3
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
/** |
186
|
|
|
|
|
|
|
* Calculate message CRC32 hash. |
187
|
|
|
|
|
|
|
* Can be called repeatedly with chunks of the message to be hashed. |
188
|
|
|
|
|
|
|
* |
189
|
|
|
|
|
|
|
* @param crc32 pointer to the hash |
190
|
|
|
|
|
|
|
* @param msg message chunk |
191
|
|
|
|
|
|
|
* @param size length of the message chunk |
192
|
|
|
|
|
|
|
*/ |
193
|
3
|
|
|
|
|
|
static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size) |
194
|
|
|
|
|
|
|
{ |
195
|
3
|
|
|
|
|
|
*crc32 = rhash_get_crc32(*crc32, msg, size); |
196
|
3
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
/** |
199
|
|
|
|
|
|
|
* Store calculated hash into the given array. |
200
|
|
|
|
|
|
|
* |
201
|
|
|
|
|
|
|
* @param crc32 pointer to the current hash value |
202
|
|
|
|
|
|
|
* @param result calculated hash in binary form |
203
|
|
|
|
|
|
|
*/ |
204
|
3
|
|
|
|
|
|
static void rhash_crc32_final(uint32_t* crc32, unsigned char* result) |
205
|
|
|
|
|
|
|
{ |
206
|
|
|
|
|
|
|
#if defined(CPU_IA32) || defined(CPU_X64) |
207
|
|
|
|
|
|
|
/* intel CPUs support assigment with non 32-bit aligned pointers */ |
208
|
3
|
|
|
|
|
|
*(unsigned*)result = be2me_32(*crc32); |
209
|
|
|
|
|
|
|
#else |
210
|
|
|
|
|
|
|
/* correct saving BigEndian integer on all archs */ |
211
|
|
|
|
|
|
|
result[0] = (unsigned char)(*crc32 >> 24), result[1] = (unsigned char)(*crc32 >> 16); |
212
|
|
|
|
|
|
|
result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32); |
213
|
|
|
|
|
|
|
#endif |
214
|
3
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
/** |
217
|
|
|
|
|
|
|
* Initialize crc32c hash. |
218
|
|
|
|
|
|
|
* |
219
|
|
|
|
|
|
|
* @param crc32c pointer to the hash to initialize |
220
|
|
|
|
|
|
|
*/ |
221
|
2
|
|
|
|
|
|
static void rhash_crc32c_init(uint32_t* crc32c) |
222
|
|
|
|
|
|
|
{ |
223
|
2
|
|
|
|
|
|
*crc32c = 0; /* note: context size is sizeof(uint32_t) */ |
224
|
2
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
/** |
227
|
|
|
|
|
|
|
* Calculate message CRC32C hash. |
228
|
|
|
|
|
|
|
* Can be called repeatedly with chunks of the message to be hashed. |
229
|
|
|
|
|
|
|
* |
230
|
|
|
|
|
|
|
* @param crc32c pointer to the hash |
231
|
|
|
|
|
|
|
* @param msg message chunk |
232
|
|
|
|
|
|
|
* @param size length of the message chunk |
233
|
|
|
|
|
|
|
*/ |
234
|
2
|
|
|
|
|
|
static void rhash_crc32c_update(uint32_t* crc32c, const unsigned char* msg, size_t size) |
235
|
|
|
|
|
|
|
{ |
236
|
2
|
|
|
|
|
|
*crc32c = rhash_get_crc32c(*crc32c, msg, size); |
237
|
2
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
/** |
240
|
|
|
|
|
|
|
* Store calculated hash into the given array. |
241
|
|
|
|
|
|
|
* |
242
|
|
|
|
|
|
|
* @param crc32c pointer to the current hash value |
243
|
|
|
|
|
|
|
* @param result calculated hash in binary form |
244
|
|
|
|
|
|
|
*/ |
245
|
2
|
|
|
|
|
|
static void rhash_crc32c_final(uint32_t* crc32c, unsigned char* result) |
246
|
|
|
|
|
|
|
{ |
247
|
|
|
|
|
|
|
#if defined(CPU_IA32) || defined(CPU_X64) |
248
|
|
|
|
|
|
|
/* intel CPUs support assigment with non 32-bit aligned pointers */ |
249
|
2
|
|
|
|
|
|
*(unsigned*)result = be2me_32(*crc32c); |
250
|
|
|
|
|
|
|
#else |
251
|
|
|
|
|
|
|
/* correct saving BigEndian integer on all archs */ |
252
|
|
|
|
|
|
|
result[0] = (unsigned char)(*crc32c >> 24), result[1] = (unsigned char)(*crc32c >> 16); |
253
|
|
|
|
|
|
|
result[2] = (unsigned char)(*crc32c >> 8), result[3] = (unsigned char)(*crc32c); |
254
|
|
|
|
|
|
|
#endif |
255
|
2
|
|
|
|
|
|
} |