1 /** 2 * TEA 3 * 4 * Copyright: 5 * (C) 1999-2007 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.block.tea; 12 13 import botan.constants; 14 static if (BOTAN_HAS_TEA): 15 16 import botan.block.block_cipher; 17 import botan.utils.loadstor; 18 import botan.utils.mem_ops; 19 20 /** 21 * TEA 22 */ 23 final class TEA : BlockCipherFixedParams!(8, 16), BlockCipher, SymmetricAlgorithm 24 { 25 public: 26 /* 27 * TEA Encryption 28 */ 29 override void encryptN(const(ubyte)* input, ubyte* output, size_t blocks) 30 { 31 foreach (size_t i; 0 .. blocks) 32 { 33 uint L = loadBigEndian!uint(input, 0); 34 uint R = loadBigEndian!uint(input, 1); 35 36 uint S = 0; 37 foreach (size_t j; 0 .. 32) 38 { 39 S += 0x9E3779B9; 40 L += ((R << 4) + m_K[0]) ^ (R + S) ^ ((R >> 5) + m_K[1]); 41 R += ((L << 4) + m_K[2]) ^ (L + S) ^ ((L >> 5) + m_K[3]); 42 } 43 44 storeBigEndian(output, L, R); 45 46 input += BLOCK_SIZE; 47 output += BLOCK_SIZE; 48 } 49 } 50 /* 51 * TEA Decryption 52 */ 53 override void decryptN(const(ubyte)* input, ubyte* output, size_t blocks) 54 { 55 foreach (size_t i; 0 .. blocks) 56 { 57 uint L = loadBigEndian!uint(input, 0); 58 uint R = loadBigEndian!uint(input, 1); 59 60 uint S = 0xC6EF3720; 61 foreach (size_t j; 0 .. 32) 62 { 63 R -= ((L << 4) + m_K[2]) ^ (L + S) ^ ((L >> 5) + m_K[3]); 64 L -= ((R << 4) + m_K[0]) ^ (R + S) ^ ((R >> 5) + m_K[1]); 65 S -= 0x9E3779B9; 66 } 67 68 storeBigEndian(output, L, R); 69 70 input += BLOCK_SIZE; 71 output += BLOCK_SIZE; 72 } 73 } 74 75 override void clear() 76 { 77 zap(m_K); 78 } 79 80 override @property string name() const { return "TEA"; } 81 override @property size_t parallelism() const { return 1; } 82 override BlockCipher clone() const { return new TEA; } 83 override size_t blockSize() const { return super.blockSize(); } 84 override KeyLengthSpecification keySpec() const { return super.keySpec(); } 85 86 protected: 87 /* 88 * TEA Key Schedule 89 */ 90 override void keySchedule(const(ubyte)* key, size_t) 91 { 92 m_K.resize(4); 93 foreach (size_t i; 0 .. 4) 94 m_K[i] = loadBigEndian!uint(key, i); 95 } 96 SecureVector!uint m_K; 97 }