/* PKCS1_V1_5.java -- 
   Copyright (C) 2003, 2006 Free Software Foundation, Inc.

This file is a part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version.  */


package gnu.javax.crypto.pad;

import gnu.java.security.Configuration;
import gnu.java.security.Registry;
import gnu.java.security.sig.rsa.EME_PKCS1_V1_5;
import gnu.java.security.util.PRNG;
import gnu.java.security.util.Util;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A padding algorithm implementation of the EME-PKCS1-V1.5 encoding/decoding
 * algorithm as described in section 7.2 of RFC-3447. This is effectively an
 * <i>Adapter</i> over an instance of {@link EME_PKCS1_V1_5} initialised with
 * the RSA public shared modulus length (in bytes).
 * <p>
 * References:
 * <ol>
 * <li><a href="http://www.ietf.org/rfc/rfc3447.txt">Public-Key Cryptography
 * Standards (PKCS) #1:</a><br>
 * RSA Cryptography Specifications Version 2.1.<br>
 * Jakob Jonsson and Burt Kaliski.</li>
 * </ol>
 * 
 * @see EME_PKCS1_V1_5
 */
public class PKCS1_V1_5
    extends BasePad
{
  private static final Logger log = Logger.getLogger(PKCS1_V1_5.class.getName());
  private EME_PKCS1_V1_5 codec;

  /**
   * Trivial package-private constructor for use by the <i>Factory</i> class.
   *
   * @see PadFactory
   */
  PKCS1_V1_5()
  {
    super(Registry.EME_PKCS1_V1_5_PAD);
  }

  public void setup()
  {
    codec = EME_PKCS1_V1_5.getInstance(blockSize);
  }

  public byte[] pad(final byte[] in, final int offset, final int length)
  {
    final byte[] M = new byte[length];
    System.arraycopy(in, offset, M, 0, length);
    final byte[] EM = codec.encode(M);
    final byte[] result = new byte[blockSize - length];
    System.arraycopy(EM, 0, result, 0, result.length);
    if (Configuration.DEBUG)
      log.fine("padding: 0x" + Util.toString(result));
    return result;
  }

  public int unpad(final byte[] in, final int offset, final int length)
      throws WrongPaddingException
  {
    final byte[] EM = new byte[length];
    System.arraycopy(in, offset, EM, 0, length);
    final int result = length - codec.decode(EM).length;
    if (Configuration.DEBUG)
      log.fine("padding length: " + String.valueOf(result));
    return result;
  }

  public boolean selfTest()
  {
    final int[] mLen = new int[] { 16, 20, 32, 48, 64 };
    final byte[] M = new byte[mLen[mLen.length - 1]];
    PRNG.getInstance().nextBytes(M);
    final byte[] EM = new byte[1024];
    byte[] p;
    int bs, i, j;
    for (bs = 256; bs < 1025; bs += 256)
      {
        init(bs);
        for (i = 0; i < mLen.length; i++)
          {
            j = mLen[i];
            p = pad(M, 0, j);
            if (j + p.length != blockSize)
              {
                if (Configuration.DEBUG)
                  log.log(Level.SEVERE,
                          "Length of padded text MUST be a multiple of "
                          + blockSize, new RuntimeException(name()));
                return false;
              }
            System.arraycopy(p, 0, EM, 0, p.length);
            System.arraycopy(M, 0, EM, p.length, j);
            try
              {
                if (p.length != unpad(EM, 0, blockSize))
                  {
                    if (Configuration.DEBUG)
                      log.log(Level.SEVERE, "Failed symmetric operation",
                              new RuntimeException(name()));
                    return false;
                  }
              }
            catch (WrongPaddingException x)
              {
                if (Configuration.DEBUG)
                  log.throwing(this.getClass().getName(), "selfTest", x);
                return false;
              }
          }
        reset();
      }
    return true;
  }
}
