/src/botan/src/lib/block/xtea/xtea.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * XTEA |
3 | | * (C) 1999-2009,2016 Jack Lloyd |
4 | | * |
5 | | * Botan is released under the Simplified BSD License (see license.txt) |
6 | | */ |
7 | | |
8 | | #include <botan/xtea.h> |
9 | | #include <botan/loadstor.h> |
10 | | |
11 | | namespace Botan { |
12 | | |
13 | | /* |
14 | | * XTEA Encryption |
15 | | */ |
16 | | void XTEA::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const |
17 | 0 | { |
18 | 0 | verify_key_set(m_EK.empty() == false); |
19 | 0 |
|
20 | 0 | const uint32_t* EK = &m_EK[0]; |
21 | 0 |
|
22 | 0 | const size_t blocks4 = blocks / 4; |
23 | 0 | const size_t blocks_left = blocks % 4; |
24 | 0 |
|
25 | 0 | BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks4; i++) |
26 | 0 | { |
27 | 0 | uint32_t L0, R0, L1, R1, L2, R2, L3, R3; |
28 | 0 | load_be(in + 4*BLOCK_SIZE*i, L0, R0, L1, R1, L2, R2, L3, R3); |
29 | 0 |
|
30 | 0 | for(size_t r = 0; r != 32; ++r) |
31 | 0 | { |
32 | 0 | L0 += (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[2*r]; |
33 | 0 | L1 += (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[2*r]; |
34 | 0 | L2 += (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[2*r]; |
35 | 0 | L3 += (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[2*r]; |
36 | 0 |
|
37 | 0 | R0 += (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[2*r+1]; |
38 | 0 | R1 += (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[2*r+1]; |
39 | 0 | R2 += (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[2*r+1]; |
40 | 0 | R3 += (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[2*r+1]; |
41 | 0 | } |
42 | 0 |
|
43 | 0 | store_be(out + 4*BLOCK_SIZE*i, L0, R0, L1, R1, L2, R2, L3, R3); |
44 | 0 | } |
45 | 0 |
|
46 | 0 | BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks_left; ++i) |
47 | 0 | { |
48 | 0 | uint32_t L, R; |
49 | 0 | load_be(in + BLOCK_SIZE*(4*blocks4+i), L, R); |
50 | 0 |
|
51 | 0 | for(size_t r = 0; r != 32; ++r) |
52 | 0 | { |
53 | 0 | L += (((R << 4) ^ (R >> 5)) + R) ^ EK[2*r]; |
54 | 0 | R += (((L << 4) ^ (L >> 5)) + L) ^ EK[2*r+1]; |
55 | 0 | } |
56 | 0 |
|
57 | 0 | store_be(out + BLOCK_SIZE*(4*blocks4+i), L, R); |
58 | 0 | } |
59 | 0 | } |
60 | | |
61 | | /* |
62 | | * XTEA Decryption |
63 | | */ |
64 | | void XTEA::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const |
65 | 0 | { |
66 | 0 | verify_key_set(m_EK.empty() == false); |
67 | 0 |
|
68 | 0 | const uint32_t* EK = &m_EK[0]; |
69 | 0 |
|
70 | 0 | const size_t blocks4 = blocks / 4; |
71 | 0 | const size_t blocks_left = blocks % 4; |
72 | 0 |
|
73 | 0 | BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks4; i++) |
74 | 0 | { |
75 | 0 | uint32_t L0, R0, L1, R1, L2, R2, L3, R3; |
76 | 0 | load_be(in + 4*BLOCK_SIZE*i, L0, R0, L1, R1, L2, R2, L3, R3); |
77 | 0 |
|
78 | 0 | for(size_t r = 0; r != 32; ++r) |
79 | 0 | { |
80 | 0 | R0 -= (((L0 << 4) ^ (L0 >> 5)) + L0) ^ EK[63 - 2*r]; |
81 | 0 | R1 -= (((L1 << 4) ^ (L1 >> 5)) + L1) ^ EK[63 - 2*r]; |
82 | 0 | R2 -= (((L2 << 4) ^ (L2 >> 5)) + L2) ^ EK[63 - 2*r]; |
83 | 0 | R3 -= (((L3 << 4) ^ (L3 >> 5)) + L3) ^ EK[63 - 2*r]; |
84 | 0 |
|
85 | 0 | L0 -= (((R0 << 4) ^ (R0 >> 5)) + R0) ^ EK[62 - 2*r]; |
86 | 0 | L1 -= (((R1 << 4) ^ (R1 >> 5)) + R1) ^ EK[62 - 2*r]; |
87 | 0 | L2 -= (((R2 << 4) ^ (R2 >> 5)) + R2) ^ EK[62 - 2*r]; |
88 | 0 | L3 -= (((R3 << 4) ^ (R3 >> 5)) + R3) ^ EK[62 - 2*r]; |
89 | 0 | } |
90 | 0 |
|
91 | 0 | store_be(out + 4*BLOCK_SIZE*i, L0, R0, L1, R1, L2, R2, L3, R3); |
92 | 0 | } |
93 | 0 |
|
94 | 0 | BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks_left; ++i) |
95 | 0 | { |
96 | 0 | uint32_t L, R; |
97 | 0 | load_be(in + BLOCK_SIZE*(4*blocks4+i), L, R); |
98 | 0 |
|
99 | 0 | for(size_t r = 0; r != 32; ++r) |
100 | 0 | { |
101 | 0 | R -= (((L << 4) ^ (L >> 5)) + L) ^ m_EK[63 - 2*r]; |
102 | 0 | L -= (((R << 4) ^ (R >> 5)) + R) ^ m_EK[62 - 2*r]; |
103 | 0 | } |
104 | 0 |
|
105 | 0 | store_be(out + BLOCK_SIZE*(4*blocks4+i), L, R); |
106 | 0 | } |
107 | 0 | } |
108 | | |
109 | | /* |
110 | | * XTEA Key Schedule |
111 | | */ |
112 | | void XTEA::key_schedule(const uint8_t key[], size_t) |
113 | 0 | { |
114 | 0 | m_EK.resize(64); |
115 | 0 |
|
116 | 0 | secure_vector<uint32_t> UK(4); |
117 | 0 | for(size_t i = 0; i != 4; ++i) |
118 | 0 | UK[i] = load_be<uint32_t>(key, i); |
119 | 0 |
|
120 | 0 | uint32_t D = 0; |
121 | 0 | for(size_t i = 0; i != 64; i += 2) |
122 | 0 | { |
123 | 0 | m_EK[i ] = D + UK[D % 4]; |
124 | 0 | D += 0x9E3779B9; |
125 | 0 | m_EK[i+1] = D + UK[(D >> 11) % 4]; |
126 | 0 | } |
127 | 0 | } |
128 | | |
129 | | void XTEA::clear() |
130 | 0 | { |
131 | 0 | zap(m_EK); |
132 | 0 | } |
133 | | |
134 | | } |