xts128.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /* ====================================================================
  2. * Copyright (c) 2011 The OpenSSL Project. 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. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. *
  16. * 3. All advertising materials mentioning features or use of this
  17. * software must display the following acknowledgment:
  18. * "This product includes software developed by the OpenSSL Project
  19. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  20. *
  21. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  22. * endorse or promote products derived from this software without
  23. * prior written permission. For written permission, please contact
  24. * openssl-core@openssl.org.
  25. *
  26. * 5. Products derived from this software may not be called "OpenSSL"
  27. * nor may "OpenSSL" appear in their names without prior written
  28. * permission of the OpenSSL Project.
  29. *
  30. * 6. Redistributions of any form whatsoever must retain the following
  31. * acknowledgment:
  32. * "This product includes software developed by the OpenSSL Project
  33. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  36. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46. * OF THE POSSIBILITY OF SUCH DAMAGE.
  47. * ====================================================================
  48. */
  49. #include <openssl/crypto.h>
  50. #include "modes_lcl.h"
  51. #include <string.h>
  52. #ifndef MODES_DEBUG
  53. # ifndef NDEBUG
  54. # define NDEBUG
  55. # endif
  56. #endif
  57. #include <assert.h>
  58. int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
  59. const unsigned char *inp, unsigned char *out,
  60. size_t len, int enc)
  61. {
  62. const union { long one; char little; } is_endian = {1};
  63. union { u64 u[2]; u32 d[4]; u8 c[16]; } tweak, scratch;
  64. unsigned int i;
  65. if (len<16) return -1;
  66. memcpy(tweak.c, iv, 16);
  67. (*ctx->block2)(tweak.c,tweak.c,ctx->key2);
  68. if (!enc && (len%16)) len-=16;
  69. while (len>=16) {
  70. #if defined(STRICT_ALIGNMENT)
  71. memcpy(scratch.c,inp,16);
  72. scratch.u[0] ^= tweak.u[0];
  73. scratch.u[1] ^= tweak.u[1];
  74. #else
  75. scratch.u[0] = ((u64*)inp)[0]^tweak.u[0];
  76. scratch.u[1] = ((u64*)inp)[1]^tweak.u[1];
  77. #endif
  78. (*ctx->block1)(scratch.c,scratch.c,ctx->key1);
  79. #if defined(STRICT_ALIGNMENT)
  80. scratch.u[0] ^= tweak.u[0];
  81. scratch.u[1] ^= tweak.u[1];
  82. memcpy(out,scratch.c,16);
  83. #else
  84. ((u64*)out)[0] = scratch.u[0]^=tweak.u[0];
  85. ((u64*)out)[1] = scratch.u[1]^=tweak.u[1];
  86. #endif
  87. inp += 16;
  88. out += 16;
  89. len -= 16;
  90. if (len==0) return 0;
  91. if (is_endian.little) {
  92. unsigned int carry,res;
  93. res = 0x87&(((int)tweak.d[3])>>31);
  94. carry = (unsigned int)(tweak.u[0]>>63);
  95. tweak.u[0] = (tweak.u[0]<<1)^res;
  96. tweak.u[1] = (tweak.u[1]<<1)|carry;
  97. }
  98. else {
  99. size_t c;
  100. for (c=0,i=0;i<16;++i) {
  101. /*+ substitutes for |, because c is 1 bit */
  102. c += ((size_t)tweak.c[i])<<1;
  103. tweak.c[i] = (u8)c;
  104. c = c>>8;
  105. }
  106. tweak.c[0] ^= (u8)(0x87&(0-c));
  107. }
  108. }
  109. if (enc) {
  110. for (i=0;i<len;++i) {
  111. u8 c = inp[i];
  112. out[i] = scratch.c[i];
  113. scratch.c[i] = c;
  114. }
  115. scratch.u[0] ^= tweak.u[0];
  116. scratch.u[1] ^= tweak.u[1];
  117. (*ctx->block1)(scratch.c,scratch.c,ctx->key1);
  118. scratch.u[0] ^= tweak.u[0];
  119. scratch.u[1] ^= tweak.u[1];
  120. memcpy(out-16,scratch.c,16);
  121. }
  122. else {
  123. union { u64 u[2]; u8 c[16]; } tweak1;
  124. if (is_endian.little) {
  125. unsigned int carry,res;
  126. res = 0x87&(((int)tweak.d[3])>>31);
  127. carry = (unsigned int)(tweak.u[0]>>63);
  128. tweak1.u[0] = (tweak.u[0]<<1)^res;
  129. tweak1.u[1] = (tweak.u[1]<<1)|carry;
  130. }
  131. else {
  132. size_t c;
  133. for (c=0,i=0;i<16;++i) {
  134. /*+ substitutes for |, because c is 1 bit */
  135. c += ((size_t)tweak.c[i])<<1;
  136. tweak1.c[i] = (u8)c;
  137. c = c>>8;
  138. }
  139. tweak1.c[0] ^= (u8)(0x87&(0-c));
  140. }
  141. #if defined(STRICT_ALIGNMENT)
  142. memcpy(scratch.c,inp,16);
  143. scratch.u[0] ^= tweak1.u[0];
  144. scratch.u[1] ^= tweak1.u[1];
  145. #else
  146. scratch.u[0] = ((u64*)inp)[0]^tweak1.u[0];
  147. scratch.u[1] = ((u64*)inp)[1]^tweak1.u[1];
  148. #endif
  149. (*ctx->block1)(scratch.c,scratch.c,ctx->key1);
  150. scratch.u[0] ^= tweak1.u[0];
  151. scratch.u[1] ^= tweak1.u[1];
  152. for (i=0;i<len;++i) {
  153. u8 c = inp[16+i];
  154. out[16+i] = scratch.c[i];
  155. scratch.c[i] = c;
  156. }
  157. scratch.u[0] ^= tweak.u[0];
  158. scratch.u[1] ^= tweak.u[1];
  159. (*ctx->block1)(scratch.c,scratch.c,ctx->key1);
  160. #if defined(STRICT_ALIGNMENT)
  161. scratch.u[0] ^= tweak.u[0];
  162. scratch.u[1] ^= tweak.u[1];
  163. memcpy (out,scratch.c,16);
  164. #else
  165. ((u64*)out)[0] = scratch.u[0]^tweak.u[0];
  166. ((u64*)out)[1] = scratch.u[1]^tweak.u[1];
  167. #endif
  168. }
  169. return 0;
  170. }