modes.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * cifra - embedded cryptography library
  3. * Written in 2014 by Joseph Birr-Pixton <jpixton@gmail.com>
  4. *
  5. * To the extent possible under law, the author(s) have dedicated all
  6. * copyright and related and neighboring rights to this software to the
  7. * public domain worldwide. This software is distributed without any
  8. * warranty.
  9. *
  10. * You should have received a copy of the CC0 Public Domain Dedication
  11. * along with this software. If not, see
  12. * <http://creativecommons.org/publicdomain/zero/1.0/>.
  13. */
  14. #include "prp.h"
  15. #include "modes.h"
  16. #include "bitops.h"
  17. #include "blockwise.h"
  18. #include <string.h>
  19. #include "tassert.h"
  20. /* CBC */
  21. void cf_cbc_init(cf_cbc *ctx, const cf_prp *prp, void *prpctx, const uint8_t iv[CF_MAXBLOCK])
  22. {
  23. ctx->prp = prp;
  24. ctx->prpctx = prpctx;
  25. memcpy(ctx->block, iv, prp->blocksz);
  26. }
  27. void cf_cbc_encrypt(cf_cbc *ctx, const uint8_t *input, uint8_t *output, size_t blocks)
  28. {
  29. uint8_t buf[CF_MAXBLOCK];
  30. size_t nblk = ctx->prp->blocksz;
  31. while (blocks--)
  32. {
  33. xor_bb(buf, input, ctx->block, nblk);
  34. ctx->prp->encrypt(ctx->prpctx, buf, ctx->block);
  35. memcpy(output, ctx->block, nblk);
  36. input += nblk;
  37. output += nblk;
  38. }
  39. }
  40. void cf_cbc_decrypt(cf_cbc *ctx, const uint8_t *input, uint8_t *output, size_t blocks)
  41. {
  42. uint8_t buf[CF_MAXBLOCK];
  43. size_t nblk = ctx->prp->blocksz;
  44. while (blocks--)
  45. {
  46. ctx->prp->decrypt(ctx->prpctx, input, buf);
  47. xor_bb(output, buf, ctx->block, nblk);
  48. memcpy(ctx->block, input, nblk);
  49. input += nblk;
  50. output += nblk;
  51. }
  52. }
  53. /* CTR */
  54. void cf_ctr_init(cf_ctr *ctx, const cf_prp *prp, void *prpctx, const uint8_t nonce[CF_MAXBLOCK])
  55. {
  56. memset(ctx, 0, sizeof *ctx);
  57. ctx->counter_offset = 0;
  58. ctx->counter_width = prp->blocksz;
  59. ctx->prp = prp;
  60. ctx->prpctx = prpctx;
  61. ctx->nkeymat = 0;
  62. memcpy(ctx->nonce, nonce, prp->blocksz);
  63. }
  64. void cf_ctr_custom_counter(cf_ctr *ctx, size_t offset, size_t width)
  65. {
  66. assert(ctx->prp->blocksz <= offset + width);
  67. ctx->counter_offset = offset;
  68. ctx->counter_width = width;
  69. }
  70. static void ctr_next_block(void *vctx, uint8_t *out)
  71. {
  72. cf_ctr *ctx = vctx;
  73. ctx->prp->encrypt(ctx->prpctx, ctx->nonce, out);
  74. incr_be(ctx->nonce + ctx->counter_offset, ctx->counter_width);
  75. }
  76. void cf_ctr_cipher(cf_ctr *ctx, const uint8_t *input, uint8_t *output, size_t bytes)
  77. {
  78. cf_blockwise_xor(ctx->keymat, &ctx->nkeymat,
  79. ctx->prp->blocksz,
  80. input, output, bytes,
  81. ctr_next_block,
  82. ctx);
  83. }
  84. void cf_ctr_discard_block(cf_ctr *ctx)
  85. {
  86. ctx->nkeymat = 0;
  87. }