1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.security; |
7 | |
8 | import org.h2.util.Utils; |
9 | |
10 | /** |
11 | * A pseudo-encryption algorithm that makes the data appear to be |
12 | * encrypted. This algorithm is cryptographically extremely weak, and should |
13 | * only be used to hide data from reading the plain text using a text editor. |
14 | */ |
15 | public class Fog implements BlockCipher { |
16 | |
17 | private int key; |
18 | |
19 | @Override |
20 | public void encrypt(byte[] bytes, int off, int len) { |
21 | for (int i = off; i < off + len; i += 16) { |
22 | encryptBlock(bytes, bytes, i); |
23 | } |
24 | } |
25 | |
26 | @Override |
27 | public void decrypt(byte[] bytes, int off, int len) { |
28 | for (int i = off; i < off + len; i += 16) { |
29 | decryptBlock(bytes, bytes, i); |
30 | } |
31 | } |
32 | |
33 | private void encryptBlock(byte[] in, byte[] out, int off) { |
34 | int x0 = (in[off] << 24) | ((in[off+1] & 255) << 16) | |
35 | ((in[off+2] & 255) << 8) | (in[off+3] & 255); |
36 | int x1 = (in[off+4] << 24) | ((in[off+5] & 255) << 16) | |
37 | ((in[off+6] & 255) << 8) | (in[off+7] & 255); |
38 | int x2 = (in[off+8] << 24) | ((in[off+9] & 255) << 16) | |
39 | ((in[off+10] & 255) << 8) | (in[off+11] & 255); |
40 | int x3 = (in[off+12] << 24) | ((in[off+13] & 255) << 16) | |
41 | ((in[off+14] & 255) << 8) | (in[off+15] & 255); |
42 | int k = key; |
43 | int s = x1 & 31; |
44 | x0 ^= k; |
45 | x0 = (x0 << s) | (x0 >>> (32 - s)); |
46 | x2 ^= k; |
47 | x2 = (x2 << s) | (x2 >>> (32 - s)); |
48 | s = x0 & 31; |
49 | x1 ^= k; |
50 | x1 = (x1 << s) | (x1 >>> (32 - s)); |
51 | x3 ^= k; |
52 | x3 = (x3 << s) | (x3 >>> (32 - s)); |
53 | out[off] = (byte) (x0 >> 24); out[off+1] = (byte) (x0 >> 16); |
54 | out[off+2] = (byte) (x0 >> 8); out[off+3] = (byte) x0; |
55 | out[off+4] = (byte) (x1 >> 24); out[off+5] = (byte) (x1 >> 16); |
56 | out[off+6] = (byte) (x1 >> 8); out[off+7] = (byte) x1; |
57 | out[off+8] = (byte) (x2 >> 24); out[off+9] = (byte) (x2 >> 16); |
58 | out[off+10] = (byte) (x2 >> 8); out[off+11] = (byte) x2; |
59 | out[off+12] = (byte) (x3 >> 24); out[off+13] = (byte) (x3 >> 16); |
60 | out[off+14] = (byte) (x3 >> 8); out[off+15] = (byte) x3; |
61 | } |
62 | |
63 | private void decryptBlock(byte[] in, byte[] out, int off) { |
64 | int x0 = (in[off] << 24) | ((in[off+1] & 255) << 16) | |
65 | ((in[off+2] & 255) << 8) | (in[off+3] & 255); |
66 | int x1 = (in[off+4] << 24) | ((in[off+5] & 255) << 16) | |
67 | ((in[off+6] & 255) << 8) | (in[off+7] & 255); |
68 | int x2 = (in[off+8] << 24) | ((in[off+9] & 255) << 16) | |
69 | ((in[off+10] & 255) << 8) | (in[off+11] & 255); |
70 | int x3 = (in[off+12] << 24) | ((in[off+13] & 255) << 16) | |
71 | ((in[off+14] & 255) << 8) | (in[off+15] & 255); |
72 | int k = key; |
73 | int s = 32 - (x0 & 31); |
74 | x1 = (x1 << s) | (x1 >>> (32 - s)); |
75 | x1 ^= k; |
76 | x3 = (x3 << s) | (x3 >>> (32 - s)); |
77 | x3 ^= k; |
78 | s = 32 - (x1 & 31); |
79 | x0 = (x0 << s) | (x0 >>> (32 - s)); |
80 | x0 ^= k; |
81 | x2 = (x2 << s) | (x2 >>> (32 - s)); |
82 | x2 ^= k; |
83 | out[off] = (byte) (x0 >> 24); out[off+1] = (byte) (x0 >> 16); |
84 | out[off+2] = (byte) (x0 >> 8); out[off+3] = (byte) x0; |
85 | out[off+4] = (byte) (x1 >> 24); out[off+5] = (byte) (x1 >> 16); |
86 | out[off+6] = (byte) (x1 >> 8); out[off+7] = (byte) x1; |
87 | out[off+8] = (byte) (x2 >> 24); out[off+9] = (byte) (x2 >> 16); |
88 | out[off+10] = (byte) (x2 >> 8); out[off+11] = (byte) x2; |
89 | out[off+12] = (byte) (x3 >> 24); out[off+13] = (byte) (x3 >> 16); |
90 | out[off+14] = (byte) (x3 >> 8); out[off+15] = (byte) x3; |
91 | } |
92 | |
93 | @Override |
94 | public int getKeyLength() { |
95 | return 16; |
96 | } |
97 | |
98 | @Override |
99 | public void setKey(byte[] key) { |
100 | this.key = (int) Utils.readLong(key, 0); |
101 | } |
102 | |
103 | } |