Skip to content

Commit

Permalink
Add support for CryptoPro S-box for GOST
Browse files Browse the repository at this point in the history
This adds a new hash identifier "gost-crypto" which uses the CryptoPro
S-box tables as specified by RFC 4357, section 11.2.
  • Loading branch information
manuelm committed Sep 4, 2013
1 parent 6ece550 commit 8ca4352
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 28 deletions.
1 change: 1 addition & 0 deletions ext/hash/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,7 @@ PHP_MINIT_FUNCTION(hash)
php_hash_register_algo("snefru", &php_hash_snefru_ops);
php_hash_register_algo("snefru256", &php_hash_snefru_ops);
php_hash_register_algo("gost", &php_hash_gost_ops);
php_hash_register_algo("gost-crypto", &php_hash_gost_crypto_ops);
php_hash_register_algo("adler32", &php_hash_adler32_ops);
php_hash_register_algo("crc32", &php_hash_crc32_ops);
php_hash_register_algo("crc32b", &php_hash_crc32b_ops);
Expand Down
71 changes: 44 additions & 27 deletions ext/hash/hash_gost.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,33 @@
* derived from gost_compress() by Markku-Juhani Saarinen <[email protected]>
*/

#define round(k1, k2) \
#define round(tables, k1, k2) \
t = (k1) + r; \
l ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \
tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24]; \
t = (k2) + l; \
r ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \
tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24];

#define R(key, h, i, t, l, r) \
#define R(tables, key, h, i, t, l, r) \
r = h[i]; \
l = h[i + 1]; \
round(key[0], key[1]) \
round(key[2], key[3]) \
round(key[4], key[5]) \
round(key[6], key[7]) \
round(key[0], key[1]) \
round(key[2], key[3]) \
round(key[4], key[5]) \
round(key[6], key[7]) \
round(key[0], key[1]) \
round(key[2], key[3]) \
round(key[4], key[5]) \
round(key[6], key[7]) \
round(key[7], key[6]) \
round(key[5], key[4]) \
round(key[3], key[2]) \
round(key[1], key[0]) \
round(tables, key[0], key[1]) \
round(tables, key[2], key[3]) \
round(tables, key[4], key[5]) \
round(tables, key[6], key[7]) \
round(tables, key[0], key[1]) \
round(tables, key[2], key[3]) \
round(tables, key[4], key[5]) \
round(tables, key[6], key[7]) \
round(tables, key[0], key[1]) \
round(tables, key[2], key[3]) \
round(tables, key[4], key[5]) \
round(tables, key[6], key[7]) \
round(tables, key[7], key[6]) \
round(tables, key[5], key[4]) \
round(tables, key[3], key[2]) \
round(tables, key[1], key[0]) \
t = r; \
r = l; \
l = t; \
Expand Down Expand Up @@ -194,10 +194,10 @@
(v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5] ^ \
(v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];

#define PASS \
#define PASS(tables) \
X(w, u, v); \
P(key, w); \
R(key, h, i, t, l, r); \
R((tables), key, h, i, t, l, r); \
S(s, l, r); \
if (i != 6) { \
A(u, l, r); \
Expand All @@ -207,16 +207,16 @@
AA(v, l, r); \
}

static inline void Gost(php_hash_uint32 state[8], php_hash_uint32 data[8])
static inline void Gost(PHP_GOST_CTX *context, php_hash_uint32 data[8])
{
int i;
php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = state, *m = data;
php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = context->state, *m = data;

memcpy(u, state, sizeof(u));
memcpy(u, context->state, sizeof(u));
memcpy(v, data, sizeof(v));

for (i = 0; i < 8; i += 2) {
PASS;
PASS(*context->tables);
}
SHIFT12(u, m, s);
SHIFT16(h, v, u);
Expand All @@ -237,12 +237,19 @@ static inline void GostTransform(PHP_GOST_CTX *context, const unsigned char inpu
temp = ((context->state[i + 8] < data[i]) || (context->state[i + 8] < save)) ? 1 : 0;
}

Gost(context->state, data);
Gost(context, data);
}

PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *context)
{
memset(context, 0, sizeof(*context));
context->tables = &tables_test;
}

PHP_HASH_API void PHP_GOSTInitCrypto(PHP_GOST_CTX *context)
{
PHP_GOSTInit(context);
context->tables = &tables_crypto;
}

static const php_hash_uint32 MAX32 = 0xffffffffLU;
Expand Down Expand Up @@ -288,9 +295,9 @@ PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context)
}

memcpy(l, context->count, sizeof(context->count));
Gost(context->state, l);
Gost(context, l);
memcpy(l, &context->state[8], sizeof(l));
Gost(context->state, l);
Gost(context, l);

for (i = 0, j = 0; j < 32; i++, j += 4) {
digest[j] = (unsigned char) (context->state[i] & 0xff);
Expand All @@ -312,6 +319,16 @@ const php_hash_ops php_hash_gost_ops = {
sizeof(PHP_GOST_CTX)
};

const php_hash_ops php_hash_gost_crypto_ops = {
(php_hash_init_func_t) PHP_GOSTInitCrypto,
(php_hash_update_func_t) PHP_GOSTUpdate,
(php_hash_final_func_t) PHP_GOSTFinal,
(php_hash_copy_func_t) php_hash_copy,
32,
32,
sizeof(PHP_GOST_CTX)
};

/*
* Local variables:
* tab-width: 4
Expand Down
1 change: 1 addition & 0 deletions ext/hash/php_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ extern const php_hash_ops php_hash_4tiger160_ops;
extern const php_hash_ops php_hash_4tiger192_ops;
extern const php_hash_ops php_hash_snefru_ops;
extern const php_hash_ops php_hash_gost_ops;
extern const php_hash_ops php_hash_gost_crypto_ops;
extern const php_hash_ops php_hash_adler32_ops;
extern const php_hash_ops php_hash_crc32_ops;
extern const php_hash_ops php_hash_crc32b_ops;
Expand Down
1 change: 1 addition & 0 deletions ext/hash/php_hash_gost.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct {
php_hash_uint32 count[2];
unsigned char length;
unsigned char buffer[32];
const php_hash_uint32 (*tables)[4][256];
} PHP_GOST_CTX;

PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *);
Expand Down
Loading

0 comments on commit 8ca4352

Please sign in to comment.