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