1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto.paddings;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.security.SecureRandom;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.InvalidCipherTextException;
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * A padder that adds Trailing-Bit-Compliment padding to a block.
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <p>
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * This padding pads the block out with the compliment of the last bit
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * of the plain text.
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * </p>
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class TBCPadding
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    implements BlockCipherPadding
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Initialise the padder.
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param random - a SecureRandom if available.
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void init(SecureRandom random)
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IllegalArgumentException
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // nothing to do.
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Return the name of the algorithm the padder implements.
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the name of the algorithm the padder implements.
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getPaddingName()
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "TBC";
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add the pad bytes to the passed in block, returning the
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * number of bytes added.
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <p>
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Note: this assumes that the last block of plain text is always
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * passed to it inside in. i.e. if inOff is zero, indicating the
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * entire block is to be overwritten with padding the value of in
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * should be the same as the last block of plain text.
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * </p>
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int addPadding(
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  in,
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     inOff)
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     count = in.length - inOff;
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte    code;
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (inOff > 0)
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            code = (byte)((in[inOff - 1] & 0x01) == 0 ? 0xff : 0x00);
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            code = (byte)((in[in.length - 1] & 0x01) == 0 ? 0xff : 0x00);
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while (inOff < in.length)
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            in[inOff] = code;
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            inOff++;
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return count;
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return the number of pad bytes present in the block.
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int padCount(byte[] in)
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws InvalidCipherTextException
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte code = in[in.length - 1];
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int index = in.length - 1;
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while (index > 0 && in[index - 1] == code)
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            index--;
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return in.length - index;
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
90