]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/modes/xts128.c
2 * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/crypto.h>
12 #include "crypto/modes.h"
14 int CRYPTO_xts128_encrypt(const XTS128_CONTEXT
*ctx
,
15 const unsigned char iv
[16],
16 const unsigned char *inp
, unsigned char *out
,
35 memcpy(tweak
.c
, iv
, 16);
37 (*ctx
->block2
) (tweak
.c
, tweak
.c
, ctx
->key2
);
39 if (!enc
&& (len
% 16))
43 #if defined(STRICT_ALIGNMENT)
44 memcpy(scratch
.c
, inp
, 16);
45 scratch
.u
[0] ^= tweak
.u
[0];
46 scratch
.u
[1] ^= tweak
.u
[1];
48 scratch
.u
[0] = ((u64
*)inp
)[0] ^ tweak
.u
[0];
49 scratch
.u
[1] = ((u64
*)inp
)[1] ^ tweak
.u
[1];
51 (*ctx
->block1
) (scratch
.c
, scratch
.c
, ctx
->key1
);
52 #if defined(STRICT_ALIGNMENT)
53 scratch
.u
[0] ^= tweak
.u
[0];
54 scratch
.u
[1] ^= tweak
.u
[1];
55 memcpy(out
, scratch
.c
, 16);
57 ((u64
*)out
)[0] = scratch
.u
[0] ^= tweak
.u
[0];
58 ((u64
*)out
)[1] = scratch
.u
[1] ^= tweak
.u
[1];
67 if (is_endian
.little
) {
68 unsigned int carry
, res
;
70 res
= 0x87 & (((int)tweak
.d
[3]) >> 31);
71 carry
= (unsigned int)(tweak
.u
[0] >> 63);
72 tweak
.u
[0] = (tweak
.u
[0] << 1) ^ res
;
73 tweak
.u
[1] = (tweak
.u
[1] << 1) | carry
;
77 for (c
= 0, i
= 0; i
< 16; ++i
) {
79 * + substitutes for |, because c is 1 bit
81 c
+= ((size_t)tweak
.c
[i
]) << 1;
85 tweak
.c
[0] ^= (u8
)(0x87 & (0 - c
));
89 for (i
= 0; i
< len
; ++i
) {
91 out
[i
] = scratch
.c
[i
];
94 scratch
.u
[0] ^= tweak
.u
[0];
95 scratch
.u
[1] ^= tweak
.u
[1];
96 (*ctx
->block1
) (scratch
.c
, scratch
.c
, ctx
->key1
);
97 scratch
.u
[0] ^= tweak
.u
[0];
98 scratch
.u
[1] ^= tweak
.u
[1];
99 memcpy(out
- 16, scratch
.c
, 16);
106 if (is_endian
.little
) {
107 unsigned int carry
, res
;
109 res
= 0x87 & (((int)tweak
.d
[3]) >> 31);
110 carry
= (unsigned int)(tweak
.u
[0] >> 63);
111 tweak1
.u
[0] = (tweak
.u
[0] << 1) ^ res
;
112 tweak1
.u
[1] = (tweak
.u
[1] << 1) | carry
;
116 for (c
= 0, i
= 0; i
< 16; ++i
) {
118 * + substitutes for |, because c is 1 bit
120 c
+= ((size_t)tweak
.c
[i
]) << 1;
124 tweak1
.c
[0] ^= (u8
)(0x87 & (0 - c
));
126 #if defined(STRICT_ALIGNMENT)
127 memcpy(scratch
.c
, inp
, 16);
128 scratch
.u
[0] ^= tweak1
.u
[0];
129 scratch
.u
[1] ^= tweak1
.u
[1];
131 scratch
.u
[0] = ((u64
*)inp
)[0] ^ tweak1
.u
[0];
132 scratch
.u
[1] = ((u64
*)inp
)[1] ^ tweak1
.u
[1];
134 (*ctx
->block1
) (scratch
.c
, scratch
.c
, ctx
->key1
);
135 scratch
.u
[0] ^= tweak1
.u
[0];
136 scratch
.u
[1] ^= tweak1
.u
[1];
138 for (i
= 0; i
< len
; ++i
) {
140 out
[16 + i
] = scratch
.c
[i
];
143 scratch
.u
[0] ^= tweak
.u
[0];
144 scratch
.u
[1] ^= tweak
.u
[1];
145 (*ctx
->block1
) (scratch
.c
, scratch
.c
, ctx
->key1
);
146 #if defined(STRICT_ALIGNMENT)
147 scratch
.u
[0] ^= tweak
.u
[0];
148 scratch
.u
[1] ^= tweak
.u
[1];
149 memcpy(out
, scratch
.c
, 16);
151 ((u64
*)out
)[0] = scratch
.u
[0] ^ tweak
.u
[0];
152 ((u64
*)out
)[1] = scratch
.u
[1] ^ tweak
.u
[1];