Filter-Rijndael

 view release on metacpan or  search on metacpan

Rijndael.xs  view on Meta::CPAN

static void
preDecrypt(int idx)
{
    /*	If the encrypted data starts with a header or needs to do some
	initialisation it can be done here 

	In this case the encrypted data has to start with a fingerprint,
	so that is checked.
    */

    SV * sv = FILTER_DATA(idx) ;
    unsigned char * buffer ;
    int i;
    SHA *state;
    char *result;
    I32 bytesread;
    unsigned char data[SHAMAXWRITESIZE];
    bzero( data, SHAMAXWRITESIZE );
    unsigned char unknown_file_type[] = "Unknown file type";

    /* read the header */
    if (ReadBlock(idx+1, sv, HEADERSIZE + CHECKSUMSIZE) != HEADERSIZE + CHECKSUMSIZE)
        croak("truncated file") ;

    buffer = (unsigned char *) SvPVX(sv);

    /* check for fingerprint of encrypted data */
    for( i = 0; i < HEADERSIZE; i++ )
      if( buffer[i] != HEADER[i] )
        croak( (unsigned char *)unknown_file_type );

    /* get file checksum */
    for( i = HEADERSIZE; i < HEADERSIZE + CHECKSUMSIZE; i++ )
        checksum[i-HEADERSIZE] = buffer[i];

    /* read file size */
    int current_location = PerlIO_tell( PL_rsfp );

    /* calculate the checksum */
    if ( ( state = shaopen( ix2alg[SHAALGORITHM] ) ) == NULL )
        croak( "Unknown checksum algorithm" );

    while(( bytesread = PerlIO_read( PL_rsfp, data, SHAMAXWRITESIZE ) ) > 0 ) {
        shawrite( data, bytesread << 3, state );
    }
    shafinish(state);

    result = (char *) shadigest(state);

    /* check the checksum */
    for( i = 0; i < shadsize(state); i++ )
        if( checksum[i] != ( result[i] & 0x000000FF ) )
            croak( (unsigned char *)unknown_file_type );

    shaclose(state);

    /* set back file position */
    PerlIO_seek( PL_rsfp, current_location, 0 );

    /* initialize Rijndael */
    ctx.mode = MODE_CBC;
    memset( iv, 0, BLOCKSIZE );
    rijndael_setup( &ctx, KEYSIZE, KEY );
}

static void
postDecrypt()
{
}

static I32
filter_decrypt(pTHX_ int idx, SV *buf_sv, int maxlen)
{
    SV   *my_sv = FILTER_DATA(idx);
    char *nl = "\n";
    char *p;
    char *out_ptr;
    int n;

    /* check if this is the first time through */
    if (FIRST_TIME(my_sv)) {

	/* Mild paranoia mode - make sure that no extra filters have 	*/
	/* been applied on the same line as the use Filter::decrypt	*/
        if (CORE_FILTER_COUNT > FILTER_COUNT(my_sv) )
	    croak("too many filters") ; 

	/* As this is the first time through, so deal with any 		*/
	/* initialisation required 					*/
        preDecrypt(idx) ;

	FIRST_TIME(my_sv) = FALSE ;
        SET_LEN(DECRYPT_SV(my_sv), 0) ;
        SET_LEN(ENCRYPT_SV(my_sv), 0) ;
        DECRYPT_OFFSET(my_sv)    = 0 ;

    }

#ifdef FDEBUG
    if (fdebug)
	warn("**** In filter_decrypt - maxlen = %d, len buf = %d idx = %d\n", 
		maxlen, SvCUR(buf_sv), idx ) ;
#endif

    while (1) {

	/* anything left from last time */
	if ((n = SvCUR(DECRYPT_SV(my_sv)))) {

	    out_ptr = SvPVX(DECRYPT_SV(my_sv)) + DECRYPT_OFFSET(my_sv) ;

	    if (maxlen) { 
		/* want a block */ 
#ifdef FDEBUG
		if (fdebug)
		    warn("BLOCK(%d): size = %d, maxlen = %d\n", 
			idx, n, maxlen) ;
#endif

	        sv_catpvn(buf_sv, out_ptr, maxlen > n ? n : maxlen );
		if(n <= maxlen) {



( run in 0.711 second using v1.01-cache-2.11-cpan-df04353d9ac )