aboutsummaryrefslogtreecommitdiffstats
path: root/cipher/gost.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cipher/gost.c235
1 files changed, 1 insertions, 234 deletions
diff --git a/cipher/gost.c b/cipher/gost.c
index 04f49261d..aaf2a8e17 100644
--- a/cipher/gost.c
+++ b/cipher/gost.c
@@ -30,280 +30,47 @@
#include "types.h"
#include "gost.h"
-
-
-static u16
-mul_inv( u16 x )
-{
- u16 t0, t1;
- u16 q, y;
-
- if( x < 2 )
- return x;
- t1 = 0x10001L / x;
- y = 0x10001L % x;
- if( y == 1 )
- return (1-t1) & 0xffff;
-
- t0 = 1;
- do {
- q = x / y;
- x = x % y;
- t0 += q * t1;
- if( x == 1 )
- return t0;
- q = y / x;
- y = y % x;
- t1 += q * t0;
- } while( y != 1 );
- return (1-t1) & 0xffff;
-}
-
-
-
-static void
-expand_key( byte *userkey, u16 *ek )
-{
- int i,j;
-
- for(j=0; j < 8; j++ ) {
- ek[j] = (*userkey << 8) + userkey[1];
- userkey += 2;
- }
- for(i=0; j < GOST_KEYLEN; j++ ) {
- i++;
- ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
- ek += i & 8;
- i &= 7;
- }
-}
-
-
-static void
-invert_key( u16 *ek, u16 dk[GOST_KEYLEN] )
-{
- int i;
- u16 t1, t2, t3;
- u16 temp[GOST_KEYLEN];
- u16 *p = temp + GOST_KEYLEN;
-
- t1 = mul_inv( *ek++ );
- t2 = -*ek++;
- t3 = -*ek++;
- *--p = mul_inv( *ek++ );
- *--p = t3;
- *--p = t2;
- *--p = t1;
-
- for(i=0; i < GOST_ROUNDS-1; i++ ) {
- t1 = *ek++;
- *--p = *ek++;
- *--p = t1;
-
- t1 = mul_inv( *ek++ );
- t2 = -*ek++;
- t3 = -*ek++;
- *--p = mul_inv( *ek++ );
- *--p = t3;
- *--p = t2;
- *--p = t1;
- }
- t1 = *ek++;
- *--p = *ek++;
- *--p = t1;
-
- t1 = mul_inv( *ek++ );
- t2 = -*ek++;
- t3 = -*ek++;
- *--p = mul_inv( *ek++ );
- *--p = t3;
- *--p = t2;
- *--p = t1;
- memcpy(dk, temp, sizeof(temp) );
- memset(temp, 0, sizeof(temp) ); /* burn temp */
-}
-
-
-static void
-cipher( byte *inbuf, byte *outbuf, u16 *key )
-{
- u16 x1, x2, x3,x4, s2, s3;
- u16 *in, *out;
- int r = GOST_ROUNDS;
- #define MUL(x,y) \
- do {u16 _t16; u32 _t32; \
- if( (_t16 = (y)) ) { \
- if( (x = (x)&0xffff) ) { \
- _t32 = (u32)x * _t16; \
- x = _t32 & 0xffff; \
- _t16 = _t32 >> 16; \
- x = ((x)-_t16) + (x<_t16?1:0); \
- } \
- else { \
- x = 1 - _t16; \
- } \
- } \
- else { \
- x = 1 - x; \
- } \
- } while(0)
-
- in = (u16*)inbuf;
- x1 = *in++;
- x2 = *in++;
- x3 = *in++;
- x4 = *in;
- #ifdef LITTLE_ENDIAN_HOST
- x1 = (x1>>8) | (x1<<8);
- x2 = (x2>>8) | (x2<<8);
- x3 = (x3>>8) | (x3<<8);
- x4 = (x4>>8) | (x4<<8);
- #endif
- do {
- MUL(x1, *key++);
- x2 += *key++;
- x3 += *key++;
- MUL(x4, *key++ );
-
- s3 = x3;
- x3 ^= x1;
- MUL(x3, *key++);
- s2 = x2;
- x2 ^=x4;
- x2 += x3;
- MUL(x2, *key++);
- x3 += x2;
-
- x1 ^= x2;
- x4 ^= x3;
-
- x2 ^= s3;
- x3 ^= s2;
- } while( --r );
- MUL(x1, *key++);
- x3 += *key++;
- x2 += *key++;
- MUL(x4, *key);
-
- out = (u16*)outbuf;
- #ifdef LITTLE_ENDIAN_HOST
- *out++ = (x1>>8) | (x1<<8);
- *out++ = (x3>>8) | (x3<<8);
- *out++ = (x2>>8) | (x2<<8);
- *out = (x4>>8) | (x4<<8);
- #else
- *out++ = x1;
- *out++ = x3;
- *out++ = x2;
- *out = x4;
- #endif
- #undef MUL
-}
+#error don't use this
void
gost_setkey( GOST_context *c, byte *key )
{
- expand_key( key, c->ek );
- invert_key( c->ek, c->dk );
}
void
gost_setiv( GOST_context *c, byte *iv )
{
- memcpy( c->iv, iv, GOST_BLOCKSIZE );
}
void
gost_encode( GOST_context *c, byte *outbuf, byte *inbuf, unsigned nblocks )
{
- unsigned n;
-
- for(n=0; n < nblocks; n++ ) {
- cipher( inbuf, outbuf, c->ek );
- inbuf += 8;
- outbuf += 8;
- }
}
void
gost_decode( GOST_context *c, byte *outbuf, byte *inbuf, unsigned nblocks )
{
- unsigned n;
-
- for(n=0; n < nblocks; n++ ) {
- cipher( inbuf, outbuf, c->dk );
- inbuf += 8;
- outbuf += 8;
- }
}
static void
cfbshift( byte *iv, byte *buf, unsigned count)
{
- unsigned n;
-
- if( count ) {
- for( n = GOST_BLOCKSIZE - count; n; n--, iv++ )
- *iv = iv[count];
- for( ; count; count-- )
- *iv++ = *buf++;
- }
}
-/****************
- * FIXME: Make use of bigger chunks
- */
-static void
-xorblock( byte *out, byte *a, byte *b, unsigned count )
-{
- for( ; count ; count--, a++, b++ )
- *out++ = *a ^ *b ;
-}
-
void
gost_encode_cfb( GOST_context *c, byte *outbuf, byte *inbuf, unsigned nbytes)
{
- byte temp[GOST_BLOCKSIZE];
-
- while( nbytes >= GOST_BLOCKSIZE ) {
- cipher( c->iv, temp, c->ek );
- xorblock( outbuf, inbuf, temp, GOST_BLOCKSIZE);
- cfbshift( c->iv, outbuf, GOST_BLOCKSIZE );
- nbytes -= GOST_BLOCKSIZE;
- inbuf += GOST_BLOCKSIZE;
- outbuf += GOST_BLOCKSIZE;
- }
- if( nbytes ) {
- cipher( c->iv, temp, c->ek );
- xorblock( outbuf, inbuf, temp, nbytes );
- cfbshift( c->iv, outbuf, nbytes );
- }
}
void
gost_decode_cfb( GOST_context *c, byte *outbuf, byte *inbuf, unsigned nbytes)
{
- byte temp[GOST_BLOCKSIZE];
-
- while( nbytes >= GOST_BLOCKSIZE ) {
- cipher( c->iv, temp, c->ek );
- cfbshift( c->iv, inbuf, GOST_BLOCKSIZE );
- xorblock( outbuf, inbuf, temp, GOST_BLOCKSIZE);
- nbytes -= GOST_BLOCKSIZE;
- inbuf += GOST_BLOCKSIZE;
- outbuf += GOST_BLOCKSIZE;
- }
- if( nbytes ) {
- cipher( c->iv, temp, c->ek );
- cfbshift( c->iv, inbuf, nbytes );
- xorblock( outbuf, inbuf, temp, nbytes );
- }
}