mech.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright 2016 Dius Computing Pty Ltd. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * - Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the
  13. * distribution.
  14. * - Neither the name of the copyright holders nor the names of
  15. * its contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  22. * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  25. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  27. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  29. * OF THE POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. * @author Johny Mattsson <jmattsson@dius.com.au>
  32. */
  33. #include "mech.h"
  34. #include "sdk-aes.h"
  35. #include "c_string.h"
  36. /* ----- AES ---------------------------------------------------------- */
  37. static const struct aes_funcs
  38. {
  39. void *(*init) (const char *key, size_t keylen);
  40. void (*crypt) (void *ctx, const char *in, char *out);
  41. void (*deinit) (void *ctx);
  42. } aes_funcs[] =
  43. {
  44. { aes_encrypt_init, aes_encrypt, aes_encrypt_deinit },
  45. { aes_decrypt_init, aes_decrypt, aes_decrypt_deinit }
  46. };
  47. static bool do_aes (crypto_op_t *co, bool with_cbc)
  48. {
  49. const struct aes_funcs *funcs = &aes_funcs[co->op];
  50. void *ctx = funcs->init (co->key, co->keylen);
  51. if (!ctx)
  52. return false;
  53. char iv[AES_BLOCKSIZE] = { 0 };
  54. if (with_cbc && co->ivlen)
  55. c_memcpy (iv, co->iv, co->ivlen < AES_BLOCKSIZE ? co->ivlen : AES_BLOCKSIZE);
  56. const char *src = co->data;
  57. char *dst = co->out;
  58. size_t left = co->datalen;
  59. while (left)
  60. {
  61. char block[AES_BLOCKSIZE] = { 0 };
  62. size_t n = left > AES_BLOCKSIZE ? AES_BLOCKSIZE : left;
  63. c_memcpy (block, src, n);
  64. if (with_cbc && co->op == OP_ENCRYPT)
  65. {
  66. const char *xor = (src == co->data) ? iv : dst - AES_BLOCKSIZE;
  67. int i;
  68. for (i = 0; i < AES_BLOCKSIZE; ++i)
  69. block[i] ^= xor[i];
  70. }
  71. funcs->crypt (ctx, block, dst);
  72. if (with_cbc && co->op == OP_DECRYPT)
  73. {
  74. const char *xor = (src == co->data) ? iv : src - AES_BLOCKSIZE;
  75. int i;
  76. for (i = 0; i < AES_BLOCKSIZE; ++i)
  77. dst[i] ^= xor[i];
  78. }
  79. left -= n;
  80. src += n;
  81. dst += n;
  82. }
  83. funcs->deinit (ctx);
  84. return true;
  85. }
  86. static bool do_aes_ecb (crypto_op_t *co)
  87. {
  88. return do_aes (co, false);
  89. }
  90. static bool do_aes_cbc (crypto_op_t *co)
  91. {
  92. return do_aes (co, true);
  93. }
  94. /* ----- mechs -------------------------------------------------------- */
  95. static const crypto_mech_t mechs[] =
  96. {
  97. { "AES-ECB", do_aes_ecb, AES_BLOCKSIZE },
  98. { "AES-CBC", do_aes_cbc, AES_BLOCKSIZE }
  99. };
  100. const crypto_mech_t *crypto_encryption_mech (const char *name)
  101. {
  102. size_t i;
  103. for (i = 0; i < sizeof (mechs) / sizeof (mechs[0]); ++i)
  104. {
  105. const crypto_mech_t *mech = mechs + i;
  106. if (strcasecmp (name, mech->name) == 0)
  107. return mech;
  108. }
  109. return 0;
  110. }