This source file includes following definitions.
- increase_counter
- _init_mcrypt
- _mcrypt_set_state
- _mcrypt_get_state
- _end_mcrypt
- xor_stuff
- _mcrypt
- _mdecrypt
- gf_crypt_register_ctr
#include <gpac/internal/crypt_dev.h>
#if !defined(GPAC_DISABLE_MCRYPT)
typedef struct ctr_buf {
u8* enc_counter;
u8* c_counter;
int c_counter_pos;
int blocksize;
} CTR_BUFFER;
static void increase_counter( u8 *x, int x_size) {
register int i, y=0;
for (i=x_size-1; i>=0; i--) {
y = 0;
if ( x[i] == 0xff) {
x[i] = 0;
y = 1;
} else x[i]++;
if (y==0) break;
}
return;
}
GF_Err _init_mcrypt( void *buf, void *key, int lenofkey, void *IV, int size)
{
((CTR_BUFFER* )buf)->c_counter = ((CTR_BUFFER* )buf)->enc_counter = NULL;
((CTR_BUFFER* )buf)->c_counter_pos = 0;
((CTR_BUFFER* )buf)->blocksize = size;
((CTR_BUFFER* )buf)->c_counter = (u8 *)gf_malloc(size);
if (((CTR_BUFFER* )buf)->c_counter==NULL) goto freeall;
((CTR_BUFFER* )buf)->enc_counter = (u8 *)gf_malloc(size);
if (((CTR_BUFFER* )buf)->enc_counter==NULL) goto freeall;
if (IV!=NULL) {
memcpy(((CTR_BUFFER* )buf)->enc_counter, IV, size);
memcpy(((CTR_BUFFER* )buf)->c_counter, IV, size);
}
return GF_OK;
freeall:
gf_free(((CTR_BUFFER* )buf)->c_counter);
gf_free(((CTR_BUFFER* )buf)->enc_counter);
return GF_OUT_OF_MEM;
}
GF_Err _mcrypt_set_state(void *_buf, void *IV, int size)
{
CTR_BUFFER* buf = (CTR_BUFFER* )_buf;
((CTR_BUFFER* )buf)->c_counter_pos = ((u8*)IV)[0];
memcpy(((CTR_BUFFER* )buf)->c_counter, &((u8*)IV)[1], size-1);
memcpy(((CTR_BUFFER* )buf)->enc_counter, &((u8*)IV)[1], size-1);
return GF_OK;
}
GF_Err _mcrypt_get_state(void *buf, void *IV, int *size)
{
if (*size < ((CTR_BUFFER* )buf)->blocksize + 1) {
*size = ((CTR_BUFFER* )buf)->blocksize + 1;
return GF_BAD_PARAM;
}
*size = ((CTR_BUFFER* )buf)->blocksize + 1;
((u8 *)IV)[0] = ((CTR_BUFFER* )buf)->c_counter_pos;
memcpy( & ((u8 *) IV)[1], ((CTR_BUFFER* )buf)->c_counter, ((CTR_BUFFER* )buf)->blocksize);
return GF_OK;
}
void _end_mcrypt(void *buf) {
gf_free(((CTR_BUFFER* )buf)->c_counter);
gf_free(((CTR_BUFFER* )buf)->enc_counter);
}
static GFINLINE
void xor_stuff( CTR_BUFFER *buf, void* akey, void (*func)(void*,void*), u8* plain, int blocksize, int xor_size)
{
void (*_mcrypt_block_encrypt) (void *, void *);
_mcrypt_block_encrypt = func;
if (xor_size == blocksize) {
if (((CTR_BUFFER* )buf)->c_counter_pos == 0) {
memcpy( ((CTR_BUFFER* )buf)->enc_counter, ((CTR_BUFFER* )buf)->c_counter, blocksize);
_mcrypt_block_encrypt(akey, ((CTR_BUFFER* )buf)->enc_counter);
memxor( plain, ((CTR_BUFFER* )buf)->enc_counter, blocksize);
increase_counter( ((CTR_BUFFER* )buf)->c_counter, blocksize);
} else {
int size = blocksize - ((CTR_BUFFER* )buf)->c_counter_pos;
memxor( plain, &((CTR_BUFFER* )buf)->enc_counter[((CTR_BUFFER* )buf)->c_counter_pos],
size);
increase_counter( ((CTR_BUFFER* )buf)->c_counter, blocksize);
memcpy( ((CTR_BUFFER* )buf)->enc_counter, ((CTR_BUFFER* )buf)->c_counter, blocksize);
_mcrypt_block_encrypt(akey, ((CTR_BUFFER* )buf)->enc_counter);
memxor( &plain[size], ((CTR_BUFFER* )buf)->enc_counter,
((CTR_BUFFER* )buf)->c_counter_pos);
}
} else {
if (((CTR_BUFFER* )buf)->c_counter_pos == 0) {
memcpy( ((CTR_BUFFER* )buf)->enc_counter, ((CTR_BUFFER* )buf)->c_counter, blocksize);
_mcrypt_block_encrypt(akey, ((CTR_BUFFER* )buf)->enc_counter);
memxor( plain, ((CTR_BUFFER* )buf)->enc_counter, xor_size);
((CTR_BUFFER* )buf)->c_counter_pos = xor_size;
} else {
int size = blocksize - ((CTR_BUFFER* )buf)->c_counter_pos;
int min_size = size < xor_size ? size: xor_size;
memxor( plain, &((CTR_BUFFER* )buf)->enc_counter[((CTR_BUFFER* )buf)->c_counter_pos],
min_size);
((CTR_BUFFER* )buf)->c_counter_pos += min_size;
if (min_size >= xor_size)
return;
increase_counter( ((CTR_BUFFER* )buf)->c_counter, blocksize);
memcpy( ((CTR_BUFFER* )buf)->enc_counter, ((CTR_BUFFER* )buf)->c_counter, blocksize);
_mcrypt_block_encrypt(akey, ((CTR_BUFFER* )buf)->enc_counter);
memxor( &plain[min_size], ((CTR_BUFFER* )buf)->enc_counter,
xor_size - min_size);
((CTR_BUFFER* )buf)->c_counter_pos = xor_size - min_size;
}
}
return;
}
GF_Err _mcrypt(void * buf,void *plaintext, int len, int blocksize, void* akey, void (*func)(void*,void*), void (*func2)(void*,void*))
{
u8 *plain;
int dlen, j=0;
int modlen;
dlen = len / blocksize;
plain = (u8 *)plaintext;
for (j = 0; j < dlen; j++) {
xor_stuff((CTR_BUFFER*) buf, akey, func, plain, blocksize, blocksize);
plain += blocksize;
}
modlen = len % blocksize;
if (modlen > 0) {
xor_stuff( (CTR_BUFFER*)buf, akey, func, plain, blocksize, modlen);
}
return GF_OK;
}
GF_Err _mdecrypt(void * buf,void *plaintext, int len, int blocksize, void* akey, void (*func)(void*,void*), void (*func2)(void*,void*))
{
return _mcrypt( buf, plaintext, len, blocksize, akey, func, func2);
}
void gf_crypt_register_ctr(GF_Crypt *td)
{
td->mode_name = "CTR";
td->_init_mcrypt = _init_mcrypt;
td->_end_mcrypt = _end_mcrypt;
td->_mcrypt = _mcrypt;
td->_mdecrypt = _mdecrypt;
td->_mcrypt_get_state = _mcrypt_get_state;
td->_mcrypt_set_state = _mcrypt_set_state;
td->has_IV = 1;
td->is_block_mode = 1;
td->is_block_algo_mode = 1;
td->mode_size = sizeof(CTR_BUFFER);
td->mode_version = 20020307;
}
#endif