예제 #1
0
static STATUS
gcn_decrypt( char *key, char *pbuff, char *passwd )
{
    CI_KS	ksch;
    char	kbuff[ CRYPT_SIZE + 1 ];
    i4		len;

    /*
    ** Validate input.
    */
    if ( key == NULL  ||  passwd == NULL )  return( FAIL );

    if ( pbuff == NULL  || *pbuff == EOS )  
    {
	*passwd = EOS;
	return( OK );
    }

    /*
    ** Adjust key to CRYPT_SIZE by padding/truncation.
    */
    for( len = 0; len < CRYPT_SIZE; len++ )  kbuff[len] = *key ? *key++ : ' ';
    kbuff[ CRYPT_SIZE ] = EOS;
    CIsetkey( kbuff, ksch );

    /*
    ** Password is passed as text, convert back to encoded 
    ** binary.  Encoded password should be of correct size.
    ** Decrypt password.
    */
    CItobin( pbuff, &len, (u_char *)passwd );
    if ( len % CRYPT_SIZE )  return( FAIL );
    CIdecode( passwd, len, ksch, passwd );

    /*
    ** Cleanup password by removing trailing
    ** spaces and the end marker.
    */
    passwd[ len ] = EOS;
    len = STtrmwhite( passwd );
    if ( passwd[ --len ] != GCN_PASSWD_END )  return( FAIL );
    passwd[ len ] = EOS;

    return( OK );
}
예제 #2
0
void
gcd_decode( char *key, u_i1 *mask, u_i1 *data, u_i2 length, char *buff )
{
    CI_KS	ks;
    u_i1	kbuff[ CRYPT_SIZE ];
    char	*ptr;
    u_i2	i, j;

    /*
    ** The key schedule is built from a single CRYPT_SIZE
    ** byte array.  We use the input key to build the byte
    ** array, truncating or duplicating as necessary.
    ** The key is also combined with an optional mask.
    */
    for( i = 0, ptr = key; i < CRYPT_SIZE; i++ )
    {
	if ( ! *ptr )  ptr = key;
	kbuff[ i ] = *ptr++ ^ (mask ? mask[ i ] : 0);
    }

    CIsetkey( (PTR)kbuff, ks );
    CIdecode( (PTR)data, length, ks, (PTR)buff );

    /*
    ** The encoded data must be padded to a multiple of
    ** CRYPT_SIZE bytes.  Random data is used for the pad,
    ** so for strings the null terminator is included in
    ** the data.  A random value is added to each block
    ** so that a given key/data pair does not encode the
    ** same way twice.  
    */
    for( i = 0, ptr = buff; i < length; i += CRYPT_SIZE )
	for( j = 1; j < CRYPT_SIZE; j++ )
	    if ( ! (*ptr++ = buff[ i + j ]) )	/* stop at EOS */
		break;

    return;
}
예제 #3
0
static STATUS
gcn_decode( char *key, u_i1 *mask, char *ipb, char *opb )
{
    CI_KS	ksch;
    char	kbuff[ CRYPT_SIZE + 1 ];
    char	*ptr;
    i4		len;

    /*
    ** Validate input.
    */
    if ( key == NULL  ||  opb == NULL )  return( FAIL );

    if ( ipb == NULL  ||  *ipb == EOS )  
    {
	*opb = EOS;
	return( OK );
    }

    if ( mask == NULL )  mask = zeros;

    /*
    ** Adjust key to CRYPT_SIZE by duplication/truncation.
    */
    for( ptr = key, len = 0; len < CRYPT_SIZE; len++ )
    {
	if ( ! *ptr )  ptr = key;
	kbuff[ len ] = *ptr++ ^ mask[ len ];
    }

    CIsetkey( kbuff, ksch );

    /*
    ** Password is passed as text, convert back to encoded 
    ** binary.  Encoded password should be of correct size.
    ** Decrypt password.
    **
    ** Decode password will be smaller than input.  The
    ** decoded password also needs to be deformatted, which
    ** can be done in place, so decode directly into output
    ** buffer.
    */
    CItobin( ipb, &len, (u_char *)opb );
    if ( len % CRYPT_SIZE )  return( FAIL );
    CIdecode( (PTR)opb, len, ksch, (PTR)opb );

    /*
    ** Remove padding and delimiter from last encryption block.
    */
    while( len  &&  (u_char)opb[ --len ] != CRYPT_DELIM );
    opb[ len ] = EOS;

    /*
    ** Extract original password by skipping random salt at
    ** start of each encryption block.
    */
    for( ptr = opb, len = 0; opb[ len ]; len++ )
	if ( len % CRYPT_SIZE )  *ptr++ = opb[ len ];

    *ptr = EOS;
    return( OK );
}