/**************** * Decrypt INBUF to OUTBUF with the mode selected at open. * inbuf and outbuf may overlap or be the same. * Depending on the mode some some contraints apply to NBYTES. */ void cipher_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) { switch( c->mode ) { case CIPHER_MODE_ECB: assert(!(nbytes%c->blocksize)); do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->blocksize ); break; case CIPHER_MODE_CBC: assert(!(nbytes%c->blocksize)); do_cbc_decrypt(c, outbuf, inbuf, nbytes/c->blocksize ); break; case CIPHER_MODE_CFB: case CIPHER_MODE_PHILS_CFB: do_cfb_decrypt(c, outbuf, inbuf, nbytes ); break; #ifdef ALLOW_DUMMY case CIPHER_MODE_DUMMY: if( inbuf != outbuf ) memmove( outbuf, inbuf, nbytes ); break; #endif default: log_fatal("cipher_decrypt: invalid mode %d\n", c->mode ); } }
/**************** * Decrypt INBUF to OUTBUF with the mode selected at open. * inbuf and outbuf may overlap or be the same. * Depending on the mode some some contraints apply to NBYTES. */ static gcry_err_code_t cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned int nbytes) { gcry_err_code_t rc = GPG_ERR_NO_ERROR; switch( c->mode ) { case GCRY_CIPHER_MODE_ECB: if (!(nbytes%c->cipher->blocksize)) do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize ); else rc = GPG_ERR_INV_ARG; break; case GCRY_CIPHER_MODE_CBC: if (!(nbytes%c->cipher->blocksize) || (nbytes > c->cipher->blocksize && (c->flags & GCRY_CIPHER_CBC_CTS))) do_cbc_decrypt(c, outbuf, inbuf, nbytes ); else rc = GPG_ERR_INV_ARG; break; case GCRY_CIPHER_MODE_CFB: do_cfb_decrypt(c, outbuf, inbuf, nbytes ); break; case GCRY_CIPHER_MODE_CTR: do_ctr_decrypt(c, outbuf, inbuf, nbytes ); break; case GCRY_CIPHER_MODE_STREAM: c->cipher->stdecrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf, nbytes ); break; case GCRY_CIPHER_MODE_NONE: if( inbuf != outbuf ) memmove( outbuf, inbuf, nbytes ); break; default: log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode ); rc = GPG_ERR_INV_CIPHER_MODE; break; } return rc; }