Crypt-Rijndael
view release on metacpan or search on metacpan
_rijndael.c view on Meta::CPAN
uint8_t block[RIJNDAEL_BLOCKSIZE];
int i, nblocks = inputlen / RIJNDAEL_BLOCKSIZE, leftover = inputlen % RIJNDAEL_BLOCKSIZE;
copy_block(iv, block);
for (i=0; i<nblocks; i++) {
rijndael_encrypt(ctx, block, block);
xor_block_with(block_no(input, i), block);
copy_block(block, block_no(output, i));
}
if (leftover) {
rijndael_encrypt(ctx, block, block);
xor_bytes_with(block_no(input, nblocks), block, leftover);
memcpy(block_no(output, nblocks), block, leftover);
}
}
static void ofb_encrypt(const RIJNDAEL_context *ctx, const uint8_t *input, int inputlen, uint8_t *output, const uint8_t *iv) {
uint8_t block[RIJNDAEL_BLOCKSIZE];
int i, nblocks = inputlen / RIJNDAEL_BLOCKSIZE, leftover = inputlen % RIJNDAEL_BLOCKSIZE;
copy_block(iv, block);
for (i=0; i<nblocks; i++) {
rijndael_encrypt(ctx, block, block);
xor_block_to(block_no(input, i), block, block_no(output, i));
}
if (leftover) {
rijndael_encrypt(ctx, block, block);
xor_bytes_to(block_no(input, nblocks), block, leftover, block_no(output, nblocks));
}
}
static void increment_counter(uint8_t* counter) {
int i = RIJNDAEL_BLOCKSIZE-1, carry_flg = 1;
while (carry_flg && i >= 0)
carry_flg = !++counter[i--];
}
static void ctr_encrypt(const RIJNDAEL_context *ctx, const uint8_t *input, int inputlen, uint8_t *output, const uint8_t *iv) {
uint8_t block[RIJNDAEL_BLOCKSIZE], counter[RIJNDAEL_BLOCKSIZE];
int i, carry_flg, nblocks = inputlen / RIJNDAEL_BLOCKSIZE, leftover = inputlen % RIJNDAEL_BLOCKSIZE;
copy_block(iv, counter);
for (i=0; i<nblocks; i++) {
rijndael_encrypt(ctx, counter, block);
xor_block_to(block, block_no(input, i), block_no(output, i));
increment_counter(counter);
}
if (leftover) {
rijndael_encrypt(ctx, counter, block);
xor_bytes_to(block, block_no(input, nblocks), leftover, block_no(output, nblocks));
/* increment_counter(counter); */
}
}
void block_encrypt(const RIJNDAEL_context *ctx, const uint8_t *input, int inputlen, uint8_t *output, const uint8_t *iv) {
switch (ctx->mode) {
case MODE_ECB: /* electronic code book */
ecb_encrypt(ctx, input, inputlen, output);
break;
case MODE_CBC: /* Cipher block chaining */
/* set initial value */
cbc_encrypt(ctx, input, inputlen, output, iv);
break;
case MODE_CFB: /* 128-bit cipher feedback */
cfb_encrypt(ctx, input, inputlen, output, iv);
break;
case MODE_OFB: /* 128-bit output feedback */
ofb_encrypt(ctx, input, inputlen, output, iv);
break;
case MODE_CTR: /* counter */
ctr_encrypt(ctx, input, inputlen, output, iv);
break;
default:
break;
}
}
static void ecb_decrypt(const RIJNDAEL_context *ctx, const uint8_t *input, int inputlen, uint8_t *output) {
int i, nblocks = inputlen / RIJNDAEL_BLOCKSIZE;
for (i = 0; i<nblocks; i++) {
rijndael_decrypt(ctx, block_no(input, i), block_no(output, i));
}
}
static void cbc_decrypt(const RIJNDAEL_context *ctx, const uint8_t *input, int inputlen, uint8_t *output, const uint8_t *iv) {
uint8_t block[RIJNDAEL_BLOCKSIZE];
int i, nblocks = inputlen / RIJNDAEL_BLOCKSIZE;
/* first block */
rijndael_decrypt(ctx, input, block);
/* XOR the block with the IV to get the output */
xor_block_to(block, iv, output);
for (i=1; i<nblocks; i++) {
rijndael_decrypt(ctx, block_no(input, i), block);
xor_block_to(block, block_no(input, i-1), block_no(output, i));
}
}
static void cfb_decrypt(const RIJNDAEL_context *ctx, const uint8_t *input, int inputlen, uint8_t *output, const uint8_t *iv) {
uint8_t block[RIJNDAEL_BLOCKSIZE];
int i, nblocks = inputlen / RIJNDAEL_BLOCKSIZE, leftover = inputlen % RIJNDAEL_BLOCKSIZE;
copy_block(iv, block);
for (i=0; i<nblocks; i++) {
rijndael_encrypt(ctx, block, block); /* ENCRYPT is right! */
xor_block_to(block, block_no(input, i), block_no(output, i));
copy_block(block_no(input, i), block);
}
if (leftover) {
rijndael_encrypt(ctx, block, block); /* ENCRYPT is right! */
xor_bytes_to(block, block_no(input, i), leftover, block_no(output, i));
memcpy(block, block_no(input, i), leftover);
}
}
void block_decrypt(const RIJNDAEL_context *ctx, const uint8_t *input, int inputlen, uint8_t *output, const uint8_t *iv) {
switch (ctx->mode) {
case MODE_ECB:
ecb_decrypt(ctx, input, inputlen, output);
break;
case MODE_CBC:
cbc_decrypt(ctx, input, inputlen, output, iv);
break;
case MODE_CFB: /* 128-bit cipher feedback */
cfb_decrypt(ctx, input, inputlen, output, iv);
break;
case MODE_OFB: /* 128-bit output feedback */
ofb_encrypt(ctx, input, inputlen, output, iv);
break;
case MODE_CTR: /* counter */
ctr_encrypt(ctx, input, inputlen, output, iv);
break;
default:
break;
}
}
( run in 0.555 second using v1.01-cache-2.11-cpan-e1769b4cff6 )