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: 60 63 95.2 %
Date: 2014-08-04 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2014 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         119 : static inline void Gost(PHP_GOST_CTX *context, php_hash_uint32 data[8])
     211             : {
     212             :         int i;
     213         119 :         php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = context->state, *m = data;
     214             :         
     215         119 :         memcpy(u, context->state, sizeof(u));
     216         119 :         memcpy(v, data, sizeof(v));
     217             :         
     218         595 :         for (i = 0; i < 8; i += 2) {
     219         476 :                 PASS(*context->tables);
     220             :         }
     221         119 :         SHIFT12(u, m, s);
     222         119 :         SHIFT16(h, v, u);
     223         119 :         SHIFT61(h, v);
     224         119 : }
     225             : /* }}} */
     226             : 
     227          59 : static inline void GostTransform(PHP_GOST_CTX *context, const unsigned char input[32])
     228             : {
     229             :         int i, j;
     230          59 :         php_hash_uint32 data[8], temp = 0, save = 0;
     231             :         
     232         531 :         for (i = 0, j = 0; i < 8; ++i, j += 4) {
     233         944 :                 data[i] =       ((php_hash_uint32) input[j]) | (((php_hash_uint32) input[j + 1]) << 8) | 
     234         472 :                                         (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24);
     235         472 :                 save = context->state[i + 8];
     236         472 :                 context->state[i + 8] += data[i] + temp;
     237         472 :                 temp = ((context->state[i + 8] < data[i]) || (context->state[i + 8] < save)) ? 1 : 0;     
     238             :         }
     239             :         
     240          59 :         Gost(context, data);
     241          59 : }
     242             : 
     243          31 : PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *context)
     244             : {
     245          31 :         memset(context, 0, sizeof(*context));
     246          31 :         context->tables = &tables_test;
     247          31 : }
     248             : 
     249          10 : PHP_HASH_API void PHP_GOSTInitCrypto(PHP_GOST_CTX *context)
     250             : {
     251          10 :         PHP_GOSTInit(context);
     252          10 :         context->tables = &tables_crypto;
     253          10 : }
     254             : 
     255             : static const php_hash_uint32 MAX32 = 0xffffffffLU;
     256             : 
     257          42 : PHP_HASH_API void PHP_GOSTUpdate(PHP_GOST_CTX *context, const unsigned char *input, size_t len)
     258             : {
     259          42 :         if ((MAX32 - context->count[0]) < (len * 8)) {
     260           0 :                 context->count[1]++;
     261           0 :                 context->count[0] = MAX32 - context->count[0];
     262           0 :                 context->count[0] = (len * 8) - context->count[0];
     263             :         } else {
     264          42 :                 context->count[0] += len * 8;
     265             :         }
     266             :         
     267          42 :         if (context->length + len < 32) {
     268          18 :                 memcpy(&context->buffer[context->length], input, len);
     269          18 :                 context->length += len;
     270             :         } else {
     271          24 :                 size_t i = 0, r = (context->length + len) % 32;
     272             :                 
     273          24 :                 if (context->length) {
     274           6 :                         i = 32 - context->length;
     275           6 :                         memcpy(&context->buffer[context->length], input, i);
     276           6 :                         GostTransform(context, context->buffer);
     277             :                 }
     278             :                 
     279          54 :                 for (; i + 32 <= len; i += 32) {
     280          30 :                         GostTransform(context, input + i);
     281             :                 }
     282             :                 
     283          24 :                 memcpy(context->buffer, input + i, r);
     284          24 :                 memset(&context->buffer[r], 0, 32 - r);
     285          24 :                 context->length = r;
     286             :         }
     287          42 : }
     288             : 
     289          30 : PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context)
     290             : {
     291          30 :         php_hash_uint32 i, j, l[8] = {0};
     292             :         
     293          30 :         if (context->length) {
     294          23 :                 GostTransform(context, context->buffer);
     295             :         }
     296             :         
     297          30 :         memcpy(l, context->count, sizeof(context->count));
     298          30 :         Gost(context, l);
     299          30 :         memcpy(l, &context->state[8], sizeof(l));
     300          30 :         Gost(context, l);
     301             :         
     302         270 :         for (i = 0, j = 0; j < 32; i++, j += 4) {
     303         240 :                 digest[j] = (unsigned char) (context->state[i] & 0xff);
     304         240 :                 digest[j + 1] = (unsigned char) ((context->state[i] >> 8) & 0xff);
     305         240 :                 digest[j + 2] = (unsigned char) ((context->state[i] >> 16) & 0xff);
     306         240 :                 digest[j + 3] = (unsigned char) ((context->state[i] >> 24) & 0xff);
     307             :         }
     308             :         
     309          30 :         memset(context, 0, sizeof(*context));
     310          30 : }
     311             : 
     312             : const php_hash_ops php_hash_gost_ops = {
     313             :         (php_hash_init_func_t) PHP_GOSTInit,
     314             :         (php_hash_update_func_t) PHP_GOSTUpdate,
     315             :         (php_hash_final_func_t) PHP_GOSTFinal,
     316             :         (php_hash_copy_func_t) php_hash_copy,
     317             :         32,
     318             :         32,
     319             :         sizeof(PHP_GOST_CTX)
     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             : };
     331             : 
     332             : /*
     333             :  * Local variables:
     334             :  * tab-width: 4
     335             :  * c-basic-offset: 4
     336             :  * End:
     337             :  * vim600: sw=4 ts=4 fdm=marker
     338             :  * vim<600: sw=4 ts=4
     339             :  */

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:04 +0000 (23 days ago)

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