i_cbc.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /*
  10. * IDEA low level APIs are deprecated for public use, but still ok for internal
  11. * use where we're using them to implement the higher level EVP interface, as is
  12. * the case here.
  13. */
  14. #include "internal/deprecated.h"
  15. #include <openssl/idea.h>
  16. #include "idea_local.h"
  17. void IDEA_cbc_encrypt(const unsigned char *in, unsigned char *out,
  18. long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
  19. int encrypt)
  20. {
  21. register unsigned long tin0, tin1;
  22. register unsigned long tout0, tout1, xor0, xor1;
  23. register long l = length;
  24. unsigned long tin[2];
  25. if (encrypt) {
  26. n2l(iv, tout0);
  27. n2l(iv, tout1);
  28. iv -= 8;
  29. for (l -= 8; l >= 0; l -= 8) {
  30. n2l(in, tin0);
  31. n2l(in, tin1);
  32. tin0 ^= tout0;
  33. tin1 ^= tout1;
  34. tin[0] = tin0;
  35. tin[1] = tin1;
  36. IDEA_encrypt(tin, ks);
  37. tout0 = tin[0];
  38. l2n(tout0, out);
  39. tout1 = tin[1];
  40. l2n(tout1, out);
  41. }
  42. if (l != -8) {
  43. n2ln(in, tin0, tin1, l + 8);
  44. tin0 ^= tout0;
  45. tin1 ^= tout1;
  46. tin[0] = tin0;
  47. tin[1] = tin1;
  48. IDEA_encrypt(tin, ks);
  49. tout0 = tin[0];
  50. l2n(tout0, out);
  51. tout1 = tin[1];
  52. l2n(tout1, out);
  53. }
  54. l2n(tout0, iv);
  55. l2n(tout1, iv);
  56. } else {
  57. n2l(iv, xor0);
  58. n2l(iv, xor1);
  59. iv -= 8;
  60. for (l -= 8; l >= 0; l -= 8) {
  61. n2l(in, tin0);
  62. tin[0] = tin0;
  63. n2l(in, tin1);
  64. tin[1] = tin1;
  65. IDEA_encrypt(tin, ks);
  66. tout0 = tin[0] ^ xor0;
  67. tout1 = tin[1] ^ xor1;
  68. l2n(tout0, out);
  69. l2n(tout1, out);
  70. xor0 = tin0;
  71. xor1 = tin1;
  72. }
  73. if (l != -8) {
  74. n2l(in, tin0);
  75. tin[0] = tin0;
  76. n2l(in, tin1);
  77. tin[1] = tin1;
  78. IDEA_encrypt(tin, ks);
  79. tout0 = tin[0] ^ xor0;
  80. tout1 = tin[1] ^ xor1;
  81. l2nn(tout0, tout1, out, l + 8);
  82. xor0 = tin0;
  83. xor1 = tin1;
  84. }
  85. l2n(xor0, iv);
  86. l2n(xor1, iv);
  87. }
  88. tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
  89. tin[0] = tin[1] = 0;
  90. }
  91. void IDEA_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key)
  92. {
  93. register IDEA_INT *p;
  94. register unsigned long x1, x2, x3, x4, t0, t1, ul;
  95. x2 = d[0];
  96. x1 = (x2 >> 16);
  97. x4 = d[1];
  98. x3 = (x4 >> 16);
  99. p = &(key->data[0][0]);
  100. E_IDEA(0);
  101. E_IDEA(1);
  102. E_IDEA(2);
  103. E_IDEA(3);
  104. E_IDEA(4);
  105. E_IDEA(5);
  106. E_IDEA(6);
  107. E_IDEA(7);
  108. x1 &= 0xffff;
  109. idea_mul(x1, x1, *p, ul);
  110. p++;
  111. t0 = x3 + *(p++);
  112. t1 = x2 + *(p++);
  113. x4 &= 0xffff;
  114. idea_mul(x4, x4, *p, ul);
  115. d[0] = (t0 & 0xffff) | ((x1 & 0xffff) << 16);
  116. d[1] = (x4 & 0xffff) | ((t1 & 0xffff) << 16);
  117. }