/* * Blowfish-CBC buffer encryption/decryption */ int blowfish_crypt_cbc( blowfish_context *ctx, int mode, size_t length, unsigned char iv[BLOWFISH_BLOCKSIZE], const unsigned char *input, unsigned char *output ) { int i; unsigned char temp[BLOWFISH_BLOCKSIZE]; if( length % BLOWFISH_BLOCKSIZE ) return( POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH ); if( mode == BLOWFISH_DECRYPT ) { while( length > 0 ) { memcpy( temp, input, BLOWFISH_BLOCKSIZE ); blowfish_crypt_ecb( ctx, mode, input, output ); for( i = 0; i < BLOWFISH_BLOCKSIZE;i++ ) output[i] = (unsigned char)( output[i] ^ iv[i] ); memcpy( iv, temp, BLOWFISH_BLOCKSIZE ); input += BLOWFISH_BLOCKSIZE; output += BLOWFISH_BLOCKSIZE; length -= BLOWFISH_BLOCKSIZE; } } else { while( length > 0 ) { for( i = 0; i < BLOWFISH_BLOCKSIZE; i++ ) output[i] = (unsigned char)( input[i] ^ iv[i] ); blowfish_crypt_ecb( ctx, mode, output, output ); memcpy( iv, output, BLOWFISH_BLOCKSIZE ); input += BLOWFISH_BLOCKSIZE; output += BLOWFISH_BLOCKSIZE; length -= BLOWFISH_BLOCKSIZE; } } return( 0 ); }
/* * Blowfish CTR buffer encryption/decryption */ int blowfish_crypt_ctr( blowfish_context *ctx, size_t length, size_t *nc_off, unsigned char nonce_counter[BLOWFISH_BLOCKSIZE], unsigned char stream_block[BLOWFISH_BLOCKSIZE], const unsigned char *input, unsigned char *output ) { int c, i; size_t n = *nc_off; while( length-- ) { if( n == 0 ) { blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, nonce_counter, stream_block ); for( i = BLOWFISH_BLOCKSIZE; i > 0; i-- ) if( ++nonce_counter[i - 1] != 0 ) break; } c = *input++; *output++ = (unsigned char)( c ^ stream_block[n] ); n = (n + 1) % BLOWFISH_BLOCKSIZE; } *nc_off = n; return( 0 ); }
/* * Blowfish CFB buffer encryption/decryption */ int blowfish_crypt_cfb64( blowfish_context *ctx, int mode, size_t length, size_t *iv_off, unsigned char iv[BLOWFISH_BLOCKSIZE], const unsigned char *input, unsigned char *output ) { int c; size_t n = *iv_off; if( mode == BLOWFISH_DECRYPT ) { while( length-- ) { if( n == 0 ) blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, iv, iv ); c = *input++; *output++ = (unsigned char)( c ^ iv[n] ); iv[n] = (unsigned char) c; n = (n + 1) % BLOWFISH_BLOCKSIZE; } } else { while( length-- ) { if( n == 0 ) blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, iv, iv ); iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); n = (n + 1) % BLOWFISH_BLOCKSIZE; } } *iv_off = n; return( 0 ); }
static int blowfish_crypt_ecb_wrap( void *ctx, operation_t operation, const unsigned char *input, unsigned char *output ) { return blowfish_crypt_ecb( (blowfish_context *) ctx, operation, input, output ); }