diff options
author | Werner Koch <[email protected]> | 1998-03-03 08:43:28 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 1998-03-03 08:43:28 +0000 |
commit | 0eb5aa6cfd145ececede8e5c6ed34f8bc9674830 (patch) | |
tree | e43b97086562b6414382b045d0221e25b243a43a /cipher/gost.c | |
parent | bug fixes (diff) | |
download | gnupg-0eb5aa6cfd145ececede8e5c6ed34f8bc9674830.tar.gz gnupg-0eb5aa6cfd145ececede8e5c6ed34f8bc9674830.zip |
v0.2.11
Diffstat (limited to '')
-rw-r--r-- | cipher/gost.c | 235 |
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 ); - } } |