Coverage Report

Created: 2025-06-13 06:58

/src/openssl32/crypto/modes/xts128gb.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2022 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
#include <string.h>
11
#include <openssl/crypto.h>
12
#include "internal/endian.h"
13
#include "crypto/modes.h"
14
15
#ifndef STRICT_ALIGNMENT
16
# ifdef __GNUC__
17
typedef u64 u64_a1 __attribute((__aligned__(1)));
18
# else
19
typedef u64 u64_a1;
20
# endif
21
#endif
22
23
int ossl_crypto_xts128gb_encrypt(const XTS128_CONTEXT *ctx,
24
                                 const unsigned char iv[16],
25
                                 const unsigned char *inp, unsigned char *out,
26
                                 size_t len, int enc)
27
0
{
28
0
    DECLARE_IS_ENDIAN;
29
0
    union {
30
0
        u64 u[2];
31
0
        u32 d[4];
32
0
        u8 c[16];
33
0
    } tweak, scratch;
34
0
    unsigned int i;
35
36
0
    if (len < 16)
37
0
        return -1;
38
39
0
    memcpy(tweak.c, iv, 16);
40
41
0
    (*ctx->block2) (tweak.c, tweak.c, ctx->key2);
42
43
0
    if (!enc && (len % 16))
44
0
        len -= 16;
45
46
0
    while (len >= 16) {
47
0
#if defined(STRICT_ALIGNMENT)
48
0
        memcpy(scratch.c, inp, 16);
49
0
        scratch.u[0] ^= tweak.u[0];
50
0
        scratch.u[1] ^= tweak.u[1];
51
#else
52
        scratch.u[0] = ((u64_a1 *)inp)[0] ^ tweak.u[0];
53
        scratch.u[1] = ((u64_a1 *)inp)[1] ^ tweak.u[1];
54
#endif
55
0
        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
56
0
#if defined(STRICT_ALIGNMENT)
57
0
        scratch.u[0] ^= tweak.u[0];
58
0
        scratch.u[1] ^= tweak.u[1];
59
0
        memcpy(out, scratch.c, 16);
60
#else
61
        ((u64_a1 *)out)[0] = scratch.u[0] ^= tweak.u[0];
62
        ((u64_a1 *)out)[1] = scratch.u[1] ^= tweak.u[1];
63
#endif
64
0
        inp += 16;
65
0
        out += 16;
66
0
        len -= 16;
67
68
0
        if (len == 0)
69
0
            return 0;
70
71
0
        if (IS_LITTLE_ENDIAN) {
72
0
            u8 res;
73
0
            u64 hi, lo;
74
#ifdef BSWAP8
75
            hi = BSWAP8(tweak.u[0]);
76
            lo = BSWAP8(tweak.u[1]);
77
#else
78
0
            u8 *p = tweak.c;
79
80
0
            hi = (u64)GETU32(p) << 32 | GETU32(p + 4);
81
0
            lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
82
0
#endif
83
0
            res = (u8)lo & 1;
84
0
            tweak.u[0] = (lo >> 1) | (hi << 63);
85
0
            tweak.u[1] = hi >> 1;
86
0
            if (res)
87
0
                tweak.c[15] ^= 0xe1;
88
#ifdef BSWAP8
89
            hi = BSWAP8(tweak.u[0]);
90
            lo = BSWAP8(tweak.u[1]);
91
#else
92
0
            p = tweak.c;
93
94
0
            hi = (u64)GETU32(p) << 32 | GETU32(p + 4);
95
0
            lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
96
0
#endif
97
0
            tweak.u[0] = lo;
98
0
            tweak.u[1] = hi;
99
0
        } else {
100
0
            u8 carry, res;
101
0
            carry = 0;
102
0
            for (i = 0; i < 16; ++i) {
103
0
                res = (tweak.c[i] << 7) & 0x80;
104
0
                tweak.c[i] = ((tweak.c[i] >> 1) + carry) & 0xff;
105
0
                carry = res;
106
0
            }
107
0
            if (res)
108
0
                tweak.c[0] ^= 0xe1;
109
0
        }
110
0
    }
111
0
    if (enc) {
112
0
        for (i = 0; i < len; ++i) {
113
0
            u8 c = inp[i];
114
0
            out[i] = scratch.c[i];
115
0
            scratch.c[i] = c;
116
0
        }
117
0
        scratch.u[0] ^= tweak.u[0];
118
0
        scratch.u[1] ^= tweak.u[1];
119
0
        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
120
0
        scratch.u[0] ^= tweak.u[0];
121
0
        scratch.u[1] ^= tweak.u[1];
122
0
        memcpy(out - 16, scratch.c, 16);
123
0
    } else {
124
0
        union {
125
0
            u64 u[2];
126
0
            u8 c[16];
127
0
        } tweak1;
128
129
0
        if (IS_LITTLE_ENDIAN) {
130
0
            u8 res;
131
0
            u64 hi, lo;
132
#ifdef BSWAP8
133
            hi = BSWAP8(tweak.u[0]);
134
            lo = BSWAP8(tweak.u[1]);
135
#else
136
0
            u8 *p = tweak.c;
137
138
0
            hi = (u64)GETU32(p) << 32 | GETU32(p + 4);
139
0
            lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
140
0
#endif
141
0
            res = (u8)lo & 1;
142
0
            tweak1.u[0] = (lo >> 1) | (hi << 63);
143
0
            tweak1.u[1] = hi >> 1;
144
0
            if (res)
145
0
                tweak1.c[15] ^= 0xe1;
146
#ifdef BSWAP8
147
            hi = BSWAP8(tweak1.u[0]);
148
            lo = BSWAP8(tweak1.u[1]);
149
#else
150
0
            p = tweak1.c;
151
152
0
            hi = (u64)GETU32(p) << 32 | GETU32(p + 4);
153
0
            lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
154
0
#endif
155
0
            tweak1.u[0] = lo;
156
0
            tweak1.u[1] = hi;
157
0
        } else {
158
0
            u8 carry, res;
159
0
            carry = 0;
160
0
            for (i = 0; i < 16; ++i) {
161
0
                res = (tweak.c[i] << 7) & 0x80;
162
0
                tweak1.c[i] = ((tweak.c[i] >> 1) + carry) & 0xff;
163
0
                carry = res;
164
0
            }
165
0
            if (res)
166
0
                tweak1.c[0] ^= 0xe1;
167
0
        }
168
0
#if defined(STRICT_ALIGNMENT)
169
0
        memcpy(scratch.c, inp, 16);
170
0
        scratch.u[0] ^= tweak1.u[0];
171
0
        scratch.u[1] ^= tweak1.u[1];
172
#else
173
        scratch.u[0] = ((u64_a1 *)inp)[0] ^ tweak1.u[0];
174
        scratch.u[1] = ((u64_a1 *)inp)[1] ^ tweak1.u[1];
175
#endif
176
0
        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
177
0
        scratch.u[0] ^= tweak1.u[0];
178
0
        scratch.u[1] ^= tweak1.u[1];
179
180
0
        for (i = 0; i < len; ++i) {
181
0
            u8 c = inp[16 + i];
182
0
            out[16 + i] = scratch.c[i];
183
0
            scratch.c[i] = c;
184
0
        }
185
0
        scratch.u[0] ^= tweak.u[0];
186
0
        scratch.u[1] ^= tweak.u[1];
187
0
        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
188
0
#if defined(STRICT_ALIGNMENT)
189
0
        scratch.u[0] ^= tweak.u[0];
190
0
        scratch.u[1] ^= tweak.u[1];
191
0
        memcpy(out, scratch.c, 16);
192
#else
193
        ((u64_a1 *)out)[0] = scratch.u[0] ^ tweak.u[0];
194
        ((u64_a1 *)out)[1] = scratch.u[1] ^ tweak.u[1];
195
#endif
196
0
    }
197
198
0
    return 0;
199
0
}