1 /* 2 +----------------------------------------------------------------------+ 3 | PHP Version 7 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1997-2018 The PHP Group | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 3.01 of the PHP license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.php.net/license/3_01.txt | 11 | If you did not receive a copy of the PHP license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@php.net so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Author: Sara Golemon <pollita@php.net> | 16 +----------------------------------------------------------------------+ 17 */ 18 19 #include "php_hash.h" 20 #include "php_hash_sha3.h" 21 22 #ifdef HAVE_SLOW_HASH3 23 // ================= slow algo ============================================== 24 25 #if (defined(__APPLE__) || defined(__APPLE_CC__)) && \ 26 (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) 27 # if defined(__LITTLE_ENDIAN__) 28 # undef WORDS_BIGENDIAN 29 # else 30 # if defined(__BIG_ENDIAN__) 31 # define WORDS_BIGENDIAN 32 # endif 33 # endif 34 #endif 35 36 static inline uint64_t rol64(uint64_t v, unsigned char b) { 37 return (v << b) | (v >> (64 - b)); 38 } 39 static inline unsigned char idx(unsigned char x, unsigned char y) { 40 return x + (5 * y); 41 } 42 43 #ifdef WORDS_BIGENDIAN 44 static inline uint64_t load64(const unsigned char* x) { 45 signed char i; 46 uint64_t ret = 0; 47 for (i = 7; i >= 0; --i) { 48 ret <<= 8; 49 ret |= x[i]; 50 } 51 return ret; 52 } 53 static inline void store64(unsigned char* x, uint64_t val) { 54 char i; 55 for (i = 0; i < 8; ++i) { 56 x[i] = val & 0xFF; 57 val >>= 8; 58 } 59 } 60 static inline void xor64(unsigned char* x, uint64_t val) { 61 char i; 62 for (i = 0; i < 8; ++i) { 63 x[i] ^= val & 0xFF; 64 val >>= 8; 65 } 66 } 67 # define readLane(x, y) load64(ctx->state+sizeof(uint64_t)*idx(x, y)) 68 # define writeLane(x, y, v) store64(ctx->state+sizeof(uint64_t)*idx(x, y), v) 69 # define XORLane(x, y, v) xor64(ctx->state+sizeof(uint64_t)*idx(x, y), v) 70 #else 71 # define readLane(x, y) (((uint64_t*)ctx->state)[idx(x,y)]) 72 # define writeLane(x, y, v) (((uint64_t*)ctx->state)[idx(x,y)] = v) 73 # define XORLane(x, y, v) (((uint64_t*)ctx->state)[idx(x,y)] ^= v) 74 #endif 75 76 static inline char LFSR86540(unsigned char* pLFSR) 77 { 78 unsigned char LFSR = *pLFSR; 79 char result = LFSR & 0x01; 80 if (LFSR & 0x80) { 81 // Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 82 LFSR = (LFSR << 1) ^ 0x71; 83 } else { 84 LFSR <<= 1; 85 } 86 *pLFSR = LFSR; 87 return result; 88 } 89 90 static void permute(PHP_SHA3_CTX* ctx) { 91 unsigned char LFSRstate = 0x01; 92 unsigned char round; 93 94 for (round = 0; round < 24; ++round) { 95 { // Theta step (see [Keccak Reference, Section 2.3.2]) 96 uint64_t C[5], D; 97 unsigned char x, y; 98 for (x = 0; x < 5; ++x) { 99 C[x] = readLane(x, 0) ^ readLane(x, 1) ^ 100 readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4); 101 } 102 for (x = 0; x < 5; ++x) { 103 D = C[(x+4)%5] ^ rol64(C[(x+1)%5], 1); 104 for (y = 0; y < 5; ++y) { 105 XORLane(x, y, D); 106 } 107 } 108 } 109 110 { // p and Pi steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) 111 unsigned char x = 1, y = 0, t; 112 uint64_t current = readLane(x, y); 113 for (t = 0; t < 24; ++t) { 114 unsigned char r = ((t + 1) * (t + 2) / 2) % 64; 115 unsigned char Y = (2*x + 3*y) % 5; 116 uint64_t temp; 117 x = y; 118 y = Y; 119 temp = readLane(x, y); 120 writeLane(x, y, rol64(current, r)); 121 current = temp; 122 } 123 } 124 125 { // X step (see [Keccak Reference, Section 2.3.1]) 126 unsigned char x, y; 127 for (y = 0; y < 5; ++y) { 128 uint64_t temp[5]; 129 for (x = 0; x < 5; ++x) { 130 temp[x] = readLane(x, y); 131 } 132 for (x = 0; x < 5; ++x) { 133 writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5])); 134 } 135 } 136 } 137 138 { // i step (see [Keccak Reference, Section 2.3.5]) 139 unsigned char j; 140 for (j = 0; j < 7; ++j) { 141 if (LFSR86540(&LFSRstate)) { 142 uint64_t bitPos = (1<<j) - 1; 143 XORLane(0, 0, (uint64_t)1 << bitPos); 144 } 145 } 146 } 147 } 148 } 149 150 // ========================================================================== 151 152 static void PHP_SHA3_Init(PHP_SHA3_CTX* ctx, 153 int bits) { 154 memset(ctx, 0, sizeof(PHP_SHA3_CTX)); 155 } 156 157 static void PHP_SHA3_Update(PHP_SHA3_CTX* ctx, 158 const unsigned char* buf, 159 unsigned int count, 160 size_t block_size) { 161 while (count > 0) { 162 unsigned int len = block_size - ctx->pos; 163 if (len > count) len = count; 164 count -= len; 165 while (len-- > 0) { 166 ctx->state[ctx->pos++] ^= *(buf++); 167 } 168 if (ctx->pos >= block_size) { 169 permute(ctx); 170 ctx->pos = 0; 171 } 172 } 173 } 174 175 static void PHP_SHA3_Final(unsigned char* digest, 176 PHP_SHA3_CTX* ctx, 177 int block_size, 178 int digest_size) { 179 int len = digest_size; 180 181 // Pad state to finalize 182 ctx->state[ctx->pos++] ^= 0x06; 183 ctx->state[block_size-1] ^= 0x80; 184 permute(ctx); 185 186 // Square output for digest 187 for(;;) { 188 int bs = (len < block_size) ? len : block_size; 189 memcpy(digest, ctx->state, bs); 190 digest += bs; 191 len -= bs; 192 if (!len) break; 193 permute(ctx); 194 } 195 196 // Zero out context 197 ZEND_SECURE_ZERO(ctx, sizeof(PHP_SHA3_CTX)); 198 } 199 200 // ========================================================================== 201 202 #define DECLARE_SHA3_OPS(bits) \ 203 void PHP_SHA3##bits##Init(PHP_SHA3_##bits##_CTX* ctx) { \ 204 PHP_SHA3_Init(ctx, bits); \ 205 } \ 206 void PHP_SHA3##bits##Update(PHP_SHA3_##bits##_CTX* ctx, \ 207 const unsigned char* input, \ 208 unsigned int inputLen) { \ 209 PHP_SHA3_Update(ctx, input, inputLen, \ 210 (1600 - (2 * bits)) >> 3); \ 211 } \ 212 void PHP_SHA3##bits##Final(unsigned char* digest, \ 213 PHP_SHA3_##bits##_CTX* ctx) { \ 214 PHP_SHA3_Final(digest, ctx, \ 215 (1600 - (2 * bits)) >> 3, \ 216 bits >> 3); \ 217 } \ 218 const php_hash_ops php_hash_sha3_##bits##_ops = { \ 219 (php_hash_init_func_t) PHP_SHA3##bits##Init, \ 220 (php_hash_update_func_t) PHP_SHA3##bits##Update, \ 221 (php_hash_final_func_t) PHP_SHA3##bits##Final, \ 222 php_hash_copy, \ 223 bits >> 3, \ 224 (1600 - (2 * bits)) >> 3, \ 225 sizeof(PHP_SHA3_##bits##_CTX), \ 226 1 \ 227 } 228 229 #else 230 231 // ================= fast algo ============================================== 232 233 #define SUCCESS SHA3_SUCCESS /* Avoid conflict between KeccacHash.h and zend_types.h */ 234 #include "KeccakHash.h" 235 236 237 // ========================================================================== 238 239 static int hash_sha3_copy(const void *ops, void *orig_context, void *dest_context) 240 { 241 PHP_SHA3_CTX* orig = (PHP_SHA3_CTX*)orig_context; 242 PHP_SHA3_CTX* dest = (PHP_SHA3_CTX*)dest_context; 243 memcpy(dest->hashinstance, orig->hashinstance, sizeof(Keccak_HashInstance)); 244 return SUCCESS; 245 } 246 247 #define DECLARE_SHA3_OPS(bits) \ 248 void PHP_SHA3##bits##Init(PHP_SHA3_##bits##_CTX* ctx) { \ 249 ctx->hashinstance = emalloc(sizeof(Keccak_HashInstance)); \ 250 Keccak_HashInitialize_SHA3_##bits((Keccak_HashInstance *)ctx->hashinstance); \ 251 } \ 252 void PHP_SHA3##bits##Update(PHP_SHA3_##bits##_CTX* ctx, \ 253 const unsigned char* input, \ 254 unsigned int inputLen) { \ 255 Keccak_HashUpdate((Keccak_HashInstance *)ctx->hashinstance, input, inputLen * 8); \ 256 } \ 257 void PHP_SHA3##bits##Final(unsigned char* digest, \ 258 PHP_SHA3_##bits##_CTX* ctx) { \ 259 Keccak_HashFinal((Keccak_HashInstance *)ctx->hashinstance, digest); \ 260 efree(ctx->hashinstance); \ 261 ctx->hashinstance = NULL; \ 262 } \ 263 const php_hash_ops php_hash_sha3_##bits##_ops = { \ 264 (php_hash_init_func_t) PHP_SHA3##bits##Init, \ 265 (php_hash_update_func_t) PHP_SHA3##bits##Update, \ 266 (php_hash_final_func_t) PHP_SHA3##bits##Final, \ 267 hash_sha3_copy, \ 268 bits >> 3, \ 269 (1600 - (2 * bits)) >> 3, \ 270 sizeof(PHP_SHA3_##bits##_CTX), \ 271 1 \ 272 } 273 274 #endif 275 // ================= both algo ============================================== 276 277 DECLARE_SHA3_OPS(224); 278 DECLARE_SHA3_OPS(256); 279 DECLARE_SHA3_OPS(384); 280 DECLARE_SHA3_OPS(512); 281 282 #undef DECLARE_SHA3_OPS 283 284 /* 285 * Local variables: 286 * tab-width: 4 287 * c-basic-offset: 4 288 * End: 289 * vim600: sw=4 ts=4 fdm=marker 290 * vim<600: sw=4 ts=4 291 */ 292