1c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrompackage org.bouncycastle.crypto.modes.gcm; 2c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.util.Pack; 46e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport org.bouncycastle.util.Arrays; 5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromabstract class GCMUtil 7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom{ 86e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom static byte[] oneAsBytes() 96e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 106e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom byte[] tmp = new byte[16]; 116e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom tmp[0] = (byte)0x80; 126e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return tmp; 136e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 146e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 156e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom static int[] oneAsInts() 166e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom int[] tmp = new int[4]; 186e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom tmp[0] = 0x80000000; 196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return tmp; 206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static int[] asInts(byte[] bs) 23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int[] us = new int[4]; 25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom us[0] = Pack.bigEndianToInt(bs, 0); 26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom us[1] = Pack.bigEndianToInt(bs, 4); 27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom us[2] = Pack.bigEndianToInt(bs, 8); 28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom us[3] = Pack.bigEndianToInt(bs, 12); 29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return us; 30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 326e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom static void multiply(byte[] block, byte[] val) 336e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 346e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom byte[] tmp = Arrays.clone(block); 356e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom byte[] c = new byte[16]; 366e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 376e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom for (int i = 0; i < 16; ++i) 386e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 396e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom byte bits = val[i]; 406e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom for (int j = 7; j >= 0; --j) 416e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 426e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if ((bits & (1 << j)) != 0) 436e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 446e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom xor(c, tmp); 456e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 466e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 476e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom boolean lsb = (tmp[15] & 1) != 0; 486e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom shiftRight(tmp); 496e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (lsb) 506e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 516e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom // R = new byte[]{ 0xe1, ... }; 526e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom// GCMUtil.xor(v, R); 536e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom tmp[0] ^= (byte)0xe1; 546e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 556e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 566e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 576e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 586e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom System.arraycopy(c, 0, block, 0, 16); 596e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 606e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // P is the value with only bit i=1 set 62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static void multiplyP(int[] x) 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean lsb = (x[3] & 1) != 0; 65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom shiftRight(x); 66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (lsb) 67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom // R = new int[]{ 0xe1000000, 0, 0, 0 }; 69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom// xor(v, R); 70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom x[0] ^= 0xe1000000; 71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static void multiplyP8(int[] x) 75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// for (int i = 8; i != 0; --i) 774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// { 784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// multiplyP(x); 794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// } 804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int lsw = x[3]; 824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom shiftRightN(x, 8); 834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom for (int i = 7; i >= 0; --i) 84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if ((lsw & (1 << i)) != 0) 864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom x[0] ^= (0xe1000000 >>> (7 - i)); 884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static void shiftRight(byte[] block) 93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int i = 0; 95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int bit = 0; 96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom for (;;) 97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int b = block[i] & 0xff; 99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom block[i] = (byte) ((b >>> 1) | bit); 100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (++i == 16) 101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom break; 103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom bit = (b & 1) << 7; 105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 107c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 108c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static void shiftRight(int[] block) 109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 110c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int i = 0; 111c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int bit = 0; 112c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom for (;;) 113c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 114c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int b = block[i]; 115c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom block[i] = (b >>> 1) | bit; 116c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (++i == 4) 117c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 118c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom break; 119c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 120c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom bit = b << 31; 121c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 122c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 123c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom static void shiftRightN(int[] block, int n) 1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int i = 0; 1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int bits = 0; 1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom for (;;) 1294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int b = block[i]; 1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom block[i] = (b >>> n) | bits; 1324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (++i == 4) 1334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom break; 1354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom bits = b << (32 - n); 1374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 140c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static void xor(byte[] block, byte[] val) 141c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 142c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom for (int i = 15; i >= 0; --i) 143c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 144c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom block[i] ^= val[i]; 145c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 146c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 147c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 148c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom static void xor(int[] block, int[] val) 149c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 150c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom for (int i = 3; i >= 0; --i) 151c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 152c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom block[i] ^= val[i]; 153c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 154c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 155c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom} 156