]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/modes/xts128.c
9dbcb5bc9a41a3133fb151149a8a43ef813e4ac3
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 #ifndef STRICT_ALIGNMENT
16 typedef u64 u64_a1
__attribute((__aligned__(1)));
22 int CRYPTO_xts128_encrypt(const XTS128_CONTEXT
*ctx
,
23 const unsigned char iv
[16],
24 const unsigned char *inp
, unsigned char *out
,
43 memcpy(tweak
.c
, iv
, 16);
45 (*ctx
->block2
) (tweak
.c
, tweak
.c
, ctx
->key2
);
47 if (!enc
&& (len
% 16))
51 #if defined(STRICT_ALIGNMENT)
52 memcpy(scratch
.c
, inp
, 16);
53 scratch
.u
[0] ^= tweak
.u
[0];
54 scratch
.u
[1] ^= tweak
.u
[1];
56 scratch
.u
[0] = ((u64_a1
*)inp
)[0] ^ tweak
.u
[0];
57 scratch
.u
[1] = ((u64_a1
*)inp
)[1] ^ tweak
.u
[1];
59 (*ctx
->block1
) (scratch
.c
, scratch
.c
, ctx
->key1
);
60 #if defined(STRICT_ALIGNMENT)
61 scratch
.u
[0] ^= tweak
.u
[0];
62 scratch
.u
[1] ^= tweak
.u
[1];
63 memcpy(out
, scratch
.c
, 16);
65 ((u64_a1
*)out
)[0] = scratch
.u
[0] ^= tweak
.u
[0];
66 ((u64_a1
*)out
)[1] = scratch
.u
[1] ^= tweak
.u
[1];
75 if (is_endian
.little
) {
76 unsigned int carry
, res
;
78 res
= 0x87 & (((int)tweak
.d
[3]) >> 31);
79 carry
= (unsigned int)(tweak
.u
[0] >> 63);
80 tweak
.u
[0] = (tweak
.u
[0] << 1) ^ res
;
81 tweak
.u
[1] = (tweak
.u
[1] << 1) | carry
;
85 for (c
= 0, i
= 0; i
< 16; ++i
) {
87 * + substitutes for |, because c is 1 bit
89 c
+= ((size_t)tweak
.c
[i
]) << 1;
93 tweak
.c
[0] ^= (u8
)(0x87 & (0 - c
));
97 for (i
= 0; i
< len
; ++i
) {
99 out
[i
] = scratch
.c
[i
];
102 scratch
.u
[0] ^= tweak
.u
[0];
103 scratch
.u
[1] ^= tweak
.u
[1];
104 (*ctx
->block1
) (scratch
.c
, scratch
.c
, ctx
->key1
);
105 scratch
.u
[0] ^= tweak
.u
[0];
106 scratch
.u
[1] ^= tweak
.u
[1];
107 memcpy(out
- 16, scratch
.c
, 16);
114 if (is_endian
.little
) {
115 unsigned int carry
, res
;
117 res
= 0x87 & (((int)tweak
.d
[3]) >> 31);
118 carry
= (unsigned int)(tweak
.u
[0] >> 63);
119 tweak1
.u
[0] = (tweak
.u
[0] << 1) ^ res
;
120 tweak1
.u
[1] = (tweak
.u
[1] << 1) | carry
;
124 for (c
= 0, i
= 0; i
< 16; ++i
) {
126 * + substitutes for |, because c is 1 bit
128 c
+= ((size_t)tweak
.c
[i
]) << 1;
132 tweak1
.c
[0] ^= (u8
)(0x87 & (0 - c
));
134 #if defined(STRICT_ALIGNMENT)
135 memcpy(scratch
.c
, inp
, 16);
136 scratch
.u
[0] ^= tweak1
.u
[0];
137 scratch
.u
[1] ^= tweak1
.u
[1];
139 scratch
.u
[0] = ((u64_a1
*)inp
)[0] ^ tweak1
.u
[0];
140 scratch
.u
[1] = ((u64_a1
*)inp
)[1] ^ tweak1
.u
[1];
142 (*ctx
->block1
) (scratch
.c
, scratch
.c
, ctx
->key1
);
143 scratch
.u
[0] ^= tweak1
.u
[0];
144 scratch
.u
[1] ^= tweak1
.u
[1];
146 for (i
= 0; i
< len
; ++i
) {
148 out
[16 + i
] = scratch
.c
[i
];
151 scratch
.u
[0] ^= tweak
.u
[0];
152 scratch
.u
[1] ^= tweak
.u
[1];
153 (*ctx
->block1
) (scratch
.c
, scratch
.c
, ctx
->key1
);
154 #if defined(STRICT_ALIGNMENT)
155 scratch
.u
[0] ^= tweak
.u
[0];
156 scratch
.u
[1] ^= tweak
.u
[1];
157 memcpy(out
, scratch
.c
, 16);
159 ((u64_a1
*)out
)[0] = scratch
.u
[0] ^ tweak
.u
[0];
160 ((u64_a1
*)out
)[1] = scratch
.u
[1] ^ tweak
.u
[1];