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 )