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 X9.23 padding to a block - if a SecureRandom is
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * passed in random padding is assumed, otherwise padding with zeros is used.
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class X923Padding
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    implements BlockCipherPadding
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    SecureRandom    random = null;
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Initialise the padder.
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param random a SecureRandom if one is available.
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void init(SecureRandom random)
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IllegalArgumentException
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.random = random;
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Return the name of the algorithm the padder implements.
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the name of the algorithm the padder implements.
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getPaddingName()
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "X9.23";
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * add the pad bytes to the passed in block, returning the
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * number of bytes added.
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int addPadding(
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  in,
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     inOff)
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte code = (byte)(in.length - inOff);
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while (inOff < in.length - 1)
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (random == null)
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                in[inOff] = 0;
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                in[inOff] = (byte)random.nextInt();
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            inOff++;
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        in[inOff] = code;
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return code;
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return the number of pad bytes present in the block.
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int padCount(byte[] in)
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws InvalidCipherTextException
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int count = in[in.length - 1] & 0xff;
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (count > in.length)
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new InvalidCipherTextException("pad block corrupted");
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return count;
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
81