PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/hash - hash_gost.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 59 62 95.2 %
Date: 2022-01-29 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             :   | Authors: Michael Wallner <mike@php.net>                              |
      16             :   |          Sara Golemon <pollita@php.net>                              |
      17             :   +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include "php_hash.h"
      23             : #include "php_hash_gost.h"
      24             : #include "php_hash_gost_tables.h"
      25             : 
      26             : /* {{{ Gost()
      27             :  * derived from gost_compress() by Markku-Juhani Saarinen <mjos@ssh.fi>
      28             :  */
      29             : 
      30             : #define round(tables, k1, k2) \
      31             :         t = (k1) + r; \
      32             :         l ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \
      33             :                 tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24]; \
      34             :         t = (k2) + l; \
      35             :         r ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \
      36             :                 tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24];
      37             : 
      38             : #define R(tables, key, h, i, t, l, r) \
      39             :         r = h[i]; \
      40             :         l = h[i + 1]; \
      41             :         round(tables, key[0], key[1]) \
      42             :         round(tables, key[2], key[3]) \
      43             :         round(tables, key[4], key[5]) \
      44             :         round(tables, key[6], key[7]) \
      45             :         round(tables, key[0], key[1]) \
      46             :         round(tables, key[2], key[3]) \
      47             :         round(tables, key[4], key[5]) \
      48             :         round(tables, key[6], key[7]) \
      49             :         round(tables, key[0], key[1]) \
      50             :         round(tables, key[2], key[3]) \
      51             :         round(tables, key[4], key[5]) \
      52             :         round(tables, key[6], key[7]) \
      53             :         round(tables, key[7], key[6]) \
      54             :         round(tables, key[5], key[4]) \
      55             :         round(tables, key[3], key[2]) \
      56             :         round(tables, key[1], key[0]) \
      57             :         t = r; \
      58             :         r = l; \
      59             :         l = t; \
      60             : 
      61             : #define X(w, u, v) \
      62             :         w[0] = u[0] ^ v[0]; \
      63             :         w[1] = u[1] ^ v[1]; \
      64             :         w[2] = u[2] ^ v[2]; \
      65             :         w[3] = u[3] ^ v[3]; \
      66             :         w[4] = u[4] ^ v[4]; \
      67             :         w[5] = u[5] ^ v[5]; \
      68             :         w[6] = u[6] ^ v[6]; \
      69             :         w[7] = u[7] ^ v[7];
      70             : 
      71             : #define P(key, w) \
      72             :         key[0] = (w[0]  & 0x000000ff) | ((w[2] & 0x000000ff) << 8) | \
      73             :                 ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24); \
      74             :         key[1] = ((w[0] & 0x0000ff00) >> 8)  | (w[2]  & 0x0000ff00) | \
      75             :                 ((w[4] & 0x0000ff00) << 8) | ((w[6] & 0x0000ff00) << 16); \
      76             :         key[2] = ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) | \
      77             :                 (w[4] & 0x00ff0000) | ((w[6] & 0x00ff0000) << 8); \
      78             :         key[3] = ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) | \
      79             :                 ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000); \
      80             :         key[4] = (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) | \
      81             :                 ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24); \
      82             :         key[5] = ((w[1] & 0x0000ff00) >> 8) | (w[3]  & 0x0000ff00) | \
      83             :                 ((w[5] & 0x0000ff00) << 8) | ((w[7] & 0x0000ff00) << 16); \
      84             :         key[6] = ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) | \
      85             :                 (w[5] & 0x00ff0000) | ((w[7] & 0x00ff0000) << 8); \
      86             :         key[7] = ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) | \
      87             :                 ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000);
      88             : 
      89             : #define A(x, l, r) \
      90             :         l = x[0] ^ x[2]; \
      91             :         r = x[1] ^ x[3]; \
      92             :         x[0] = x[2]; \
      93             :         x[1] = x[3]; \
      94             :         x[2] = x[4]; \
      95             :         x[3] = x[5]; \
      96             :         x[4] = x[6]; \
      97             :         x[5] = x[7]; \
      98             :         x[6] = l; \
      99             :         x[7] = r;
     100             : 
     101             : #define AA(x, l, r) \
     102             :         l = x[0]; \
     103             :         r = x[2]; \
     104             :         x[0] = x[4]; \
     105             :         x[2] = x[6]; \
     106             :         x[4] = l ^ r; \
     107             :         x[6] = x[0] ^ r; \
     108             :         l = x[1]; \
     109             :         r = x[3]; \
     110             :         x[1] = x[5]; \
     111             :         x[3] = x[7]; \
     112             :         x[5] = l ^ r; \
     113             :         x[7] = x[1] ^ r;
     114             : 
     115             : #define C(x) \
     116             :         x[0] ^= 0xff00ff00; \
     117             :         x[1] ^= 0xff00ff00; \
     118             :         x[2] ^= 0x00ff00ff; \
     119             :         x[3] ^= 0x00ff00ff; \
     120             :         x[4] ^= 0x00ffff00; \
     121             :         x[5] ^= 0xff0000ff; \
     122             :         x[6] ^= 0x000000ff; \
     123             :         x[7] ^= 0xff00ffff;
     124             : 
     125             : #define S(s, l, r) \
     126             :                 s[i] = r; \
     127             :                 s[i + 1] = l;
     128             : 
     129             : #define SHIFT12(u, m, s) \
     130             :         u[0] = m[0] ^ s[6]; \
     131             :         u[1] = m[1] ^ s[7]; \
     132             :         u[2] = m[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ \
     133             :                 (s[1] & 0xffff) ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ \
     134             :                 (s[7] & 0xffff0000) ^ (s[7] >> 16); \
     135             :         u[3] = m[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ \
     136             :                 (s[1] << 16) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ \
     137             :                 (s[3] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ \
     138             :                 (s[7] << 16) ^ (s[7] >> 16); \
     139             :         u[4] = m[4] ^ \
     140             :                 (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^ \
     141             :                 (s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ \
     142             :                 (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ \
     143             :                 (s[6] >> 16) ^(s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16); \
     144             :         u[5] = m[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^ \
     145             :                 (s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ \
     146             :                 (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^  (s[6] << 16) ^ \
     147             :                 (s[6] >> 16) ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16); \
     148             :         u[6] = m[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16) ^ \
     149             :                 (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6] ^ \
     150             :                 (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16); \
     151             :         u[7] = m[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ \
     152             :                 (s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^ \
     153             :                 (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ \
     154             :                 (s[7] << 16) ^ (s[7] >> 16);
     155             : 
     156             : #define SHIFT16(h, v, u) \
     157             :         v[0] = h[0] ^ (u[1] << 16) ^ (u[0] >> 16); \
     158             :         v[1] = h[1] ^ (u[2] << 16) ^ (u[1] >> 16); \
     159             :         v[2] = h[2] ^ (u[3] << 16) ^ (u[2] >> 16); \
     160             :         v[3] = h[3] ^ (u[4] << 16) ^ (u[3] >> 16); \
     161             :         v[4] = h[4] ^ (u[5] << 16) ^ (u[4] >> 16); \
     162             :         v[5] = h[5] ^ (u[6] << 16) ^ (u[5] >> 16); \
     163             :         v[6] = h[6] ^ (u[7] << 16) ^ (u[6] >> 16); \
     164             :         v[7] = h[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[7] >> 16) ^ \
     165             :                 (u[1] & 0xffff0000) ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000);
     166             : 
     167             : #define SHIFT61(h, v) \
     168             :         h[0] = (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^ (v[1] >> 16) ^ \
     169             :                 (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ (v[4] << 16) ^ \
     170             :                 (v[5] >> 16) ^ v[5] ^ (v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ \
     171             :                 (v[7] & 0xffff); \
     172             :         h[1] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ (v[1] & 0xffff) ^ \
     173             :         v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^ (v[4] >> 16) ^ (v[5] << 16) ^ \
     174             :                 (v[6] << 16) ^ v[6] ^ (v[7] & 0xffff0000) ^ (v[7] >> 16); \
     175             :         h[2] = (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ \
     176             :                 (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ \
     177             :                 (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^ (v[7] & 0xffff) ^ (v[7] << 16) ^ \
     178             :                 (v[7] >> 16); \
     179             :         h[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ \
     180             :                 (v[1] & 0xffff0000) ^ (v[1] >> 16) ^ (v[2] << 16) ^ (v[2] >> 16) ^ v[2] ^ \
     181             :                 (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ \
     182             :                 (v[7] & 0xffff) ^ (v[7] >> 16); \
     183             :         h[4] = (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^ \
     184             :                 (v[3] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ \
     185             :         v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16); \
     186             :         h[5] = (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^ (v[1] >> 16) ^ \
     187             :                 (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^ (v[3] >> 16) ^ v[3] ^ \
     188             :                 (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ \
     189             :                 (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff0000); \
     190             :         h[6] = v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^ \
     191             :                 (v[4] >> 16) ^ (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ \
     192             :                 (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ v[7]; \
     193             :         h[7] = v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ (v[2] << 16) ^ \
     194             :                 (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5] ^ \
     195             :                 (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];
     196             : 
     197             : #define PASS(tables) \
     198             :         X(w, u, v); \
     199             :         P(key, w); \
     200             :         R((tables), key, h, i, t, l, r); \
     201             :         S(s, l, r); \
     202             :         if (i != 6) { \
     203             :                 A(u, l, r); \
     204             :                 if (i == 2)     { \
     205             :                         C(u); \
     206             :                 } \
     207             :                 AA(v, l, r); \
     208             :         }
     209             : 
     210         181 : static inline void Gost(PHP_GOST_CTX *context, uint32_t data[8])
     211             : {
     212             :         int i;
     213         181 :         uint32_t l, r, t, key[8], u[8], v[8], w[8], s[8], *h = context->state, *m = data;
     214             : 
     215         181 :         memcpy(u, context->state, sizeof(u));
     216         181 :         memcpy(v, data, sizeof(v));
     217             : 
     218         905 :         for (i = 0; i < 8; i += 2) {
     219         724 :                 PASS(*context->tables);
     220             :         }
     221         181 :         SHIFT12(u, m, s);
     222         181 :         SHIFT16(h, v, u);
     223         181 :         SHIFT61(h, v);
     224         181 : }
     225             : /* }}} */
     226             : 
     227          85 : static inline void GostTransform(PHP_GOST_CTX *context, const unsigned char input[32])
     228             : {
     229             :         int i, j;
     230          85 :         uint32_t data[8], temp = 0;
     231             : 
     232         765 :         for (i = 0, j = 0; i < 8; ++i, j += 4) {
     233        2040 :                 data[i] =       ((uint32_t) input[j]) | (((uint32_t) input[j + 1]) << 8) |
     234        1360 :                                         (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24);
     235         680 :                 context->state[i + 8] += data[i] + temp;
     236         680 :                 temp = context->state[i + 8] < data[i] ? 1 : (context->state[i + 8] == data[i] ? temp : 0);
     237             :         }
     238             : 
     239          85 :         Gost(context, data);
     240          85 : }
     241             : 
     242          50 : PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *context)
     243             : {
     244          50 :         memset(context, 0, sizeof(*context));
     245          50 :         context->tables = &tables_test;
     246          50 : }
     247             : 
     248          17 : PHP_HASH_API void PHP_GOSTInitCrypto(PHP_GOST_CTX *context)
     249             : {
     250          17 :         PHP_GOSTInit(context);
     251          17 :         context->tables = &tables_crypto;
     252          17 : }
     253             : 
     254             : static const uint32_t MAX32 = 0xffffffffLU;
     255             : 
     256          62 : PHP_HASH_API void PHP_GOSTUpdate(PHP_GOST_CTX *context, const unsigned char *input, size_t len)
     257             : {
     258          62 :         if ((MAX32 - context->count[0]) < (len * 8)) {
     259           0 :                 context->count[1]++;
     260           0 :                 context->count[0] = MAX32 - context->count[0];
     261           0 :                 context->count[0] = (len * 8) - context->count[0];
     262             :         } else {
     263          62 :                 context->count[0] += len * 8;
     264             :         }
     265             : 
     266          62 :         if (context->length + len < 32) {
     267          26 :                 memcpy(&context->buffer[context->length], input, len);
     268          26 :                 context->length += len;
     269             :         } else {
     270          36 :                 size_t i = 0, r = (context->length + len) % 32;
     271             : 
     272          36 :                 if (context->length) {
     273           8 :                         i = 32 - context->length;
     274           8 :                         memcpy(&context->buffer[context->length], input, i);
     275           8 :                         GostTransform(context, context->buffer);
     276             :                 }
     277             : 
     278          76 :                 for (; i + 32 <= len; i += 32) {
     279          40 :                         GostTransform(context, input + i);
     280             :                 }
     281             : 
     282          36 :                 memcpy(context->buffer, input + i, r);
     283          36 :                 ZEND_SECURE_ZERO(&context->buffer[r], 32 - r);
     284          36 :                 context->length = r;
     285             :         }
     286          62 : }
     287             : 
     288          48 : PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context)
     289             : {
     290          48 :         uint32_t i, j, l[8] = {0};
     291             : 
     292          48 :         if (context->length) {
     293          37 :                 GostTransform(context, context->buffer);
     294             :         }
     295             : 
     296          48 :         memcpy(l, context->count, sizeof(context->count));
     297          48 :         Gost(context, l);
     298          48 :         memcpy(l, &context->state[8], sizeof(l));
     299          48 :         Gost(context, l);
     300             : 
     301         432 :         for (i = 0, j = 0; j < 32; i++, j += 4) {
     302         384 :                 digest[j] = (unsigned char) (context->state[i] & 0xff);
     303         384 :                 digest[j + 1] = (unsigned char) ((context->state[i] >> 8) & 0xff);
     304         384 :                 digest[j + 2] = (unsigned char) ((context->state[i] >> 16) & 0xff);
     305         384 :                 digest[j + 3] = (unsigned char) ((context->state[i] >> 24) & 0xff);
     306             :         }
     307             : 
     308          48 :         ZEND_SECURE_ZERO(context, sizeof(*context));
     309          48 : }
     310             : 
     311             : const php_hash_ops php_hash_gost_ops = {
     312             :         (php_hash_init_func_t) PHP_GOSTInit,
     313             :         (php_hash_update_func_t) PHP_GOSTUpdate,
     314             :         (php_hash_final_func_t) PHP_GOSTFinal,
     315             :         (php_hash_copy_func_t) php_hash_copy,
     316             :         32,
     317             :         32,
     318             :         sizeof(PHP_GOST_CTX),
     319             :         1
     320             : };
     321             : 
     322             : const php_hash_ops php_hash_gost_crypto_ops = {
     323             :         (php_hash_init_func_t) PHP_GOSTInitCrypto,
     324             :         (php_hash_update_func_t) PHP_GOSTUpdate,
     325             :         (php_hash_final_func_t) PHP_GOSTFinal,
     326             :         (php_hash_copy_func_t) php_hash_copy,
     327             :         32,
     328             :         32,
     329             :         sizeof(PHP_GOST_CTX),
     330             :         1
     331             : };
     332             : 
     333             : /*
     334             :  * Local variables:
     335             :  * tab-width: 4
     336             :  * c-basic-offset: 4
     337             :  * End:
     338             :  * vim600: sw=4 ts=4 fdm=marker
     339             :  * vim<600: sw=4 ts=4
     340             :  */

Generated by: LCOV version 1.10

Generated at Sat, 29 Jan 2022 07:14:32 +0000 (1 hour ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.