OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [crypto/] [RSACipherImpl.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* RSACipherImpl.java --
2
   Copyright (C) 2005, 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.javax.crypto;
40
 
41
import gnu.classpath.debug.Component;
42
import gnu.classpath.debug.SystemLogger;
43
import gnu.java.security.sig.rsa.EME_PKCS1_V1_5;
44
import gnu.java.security.util.ByteArray;
45
 
46
import java.math.BigInteger;
47
import java.security.AlgorithmParameters;
48
import java.security.InvalidKeyException;
49
import java.security.Key;
50
import java.security.NoSuchAlgorithmException;
51
import java.security.SecureRandom;
52
import java.security.interfaces.RSAKey;
53
import java.security.interfaces.RSAPrivateCrtKey;
54
import java.security.interfaces.RSAPrivateKey;
55
import java.security.interfaces.RSAPublicKey;
56
import java.security.spec.AlgorithmParameterSpec;
57
 
58
import javax.crypto.BadPaddingException;
59
import javax.crypto.Cipher;
60
import javax.crypto.CipherSpi;
61
import javax.crypto.IllegalBlockSizeException;
62
import javax.crypto.NoSuchPaddingException;
63
import javax.crypto.ShortBufferException;
64
 
65
public class RSACipherImpl
66
    extends CipherSpi
67
{
68
  private static final SystemLogger logger = SystemLogger.SYSTEM;
69
 
70
  private static final byte[] EMPTY = new byte[0];
71
  private int opmode = -1;
72
  private RSAPrivateKey decipherKey = null;
73
  private RSAPublicKey blindingKey = null;
74
  private RSAPublicKey encipherKey = null;
75
  private SecureRandom random = null;
76
  private byte[] dataBuffer = null;
77
  private int pos = 0;
78
 
79
  protected void engineSetMode(String mode) throws NoSuchAlgorithmException
80
  {
81
    throw new NoSuchAlgorithmException("only one mode available");
82
  }
83
 
84
  protected void engineSetPadding(String pad) throws NoSuchPaddingException
85
  {
86
    throw new NoSuchPaddingException("only one padding available");
87
  }
88
 
89
  protected int engineGetBlockSize()
90
  {
91
    return 1;
92
  }
93
 
94
  protected int engineGetOutputSize(int inputLen)
95
  {
96
    int outputLen = 0;
97
    if (decipherKey != null)
98
      outputLen = (decipherKey.getModulus().bitLength() + 7) / 8;
99
    else if (encipherKey != null)
100
      outputLen = (encipherKey.getModulus().bitLength() + 7) / 8;
101
    else
102
      throw new IllegalStateException("not initialized");
103
    if (inputLen > outputLen)
104
      throw new IllegalArgumentException("not configured to encode " + inputLen
105
                                         + "bytes; at most " + outputLen);
106
    return outputLen;
107
  }
108
 
109
  protected int engineGetKeySize(final Key key) throws InvalidKeyException
110
  {
111
    if (! (key instanceof RSAKey))
112
      throw new InvalidKeyException("not an RSA key");
113
    return ((RSAKey) key).getModulus().bitLength();
114
  }
115
 
116
  protected byte[] engineGetIV()
117
  {
118
    return null;
119
  }
120
 
121
  protected AlgorithmParameters engineGetParameters()
122
  {
123
    return null;
124
  }
125
 
126
  protected void engineInit(int opmode, Key key, SecureRandom random)
127
      throws InvalidKeyException
128
  {
129
    int outputLen = 0;
130
    if (opmode == Cipher.ENCRYPT_MODE)
131
      {
132
        if (! (key instanceof RSAPublicKey))
133
          throw new InvalidKeyException("expecting a RSAPublicKey");
134
        encipherKey = (RSAPublicKey) key;
135
        decipherKey = null;
136
        blindingKey = null;
137
        outputLen = (encipherKey.getModulus().bitLength() + 7) / 8;
138
      }
139
    else if (opmode == Cipher.DECRYPT_MODE)
140
      {
141
        if (key instanceof RSAPrivateKey)
142
          {
143
            decipherKey = (RSAPrivateKey) key;
144
            encipherKey = null;
145
            blindingKey = null;
146
            outputLen = (decipherKey.getModulus().bitLength() + 7) / 8;
147
          }
148
        else if (key instanceof RSAPublicKey)
149
          {
150
            if (decipherKey == null)
151
              throw new IllegalStateException("must configure decryption key first");
152
            if (! decipherKey.getModulus().equals(((RSAPublicKey) key).getModulus()))
153
              throw new InvalidKeyException("blinding key is not compatible");
154
            blindingKey = (RSAPublicKey) key;
155
            return;
156
          }
157
        else
158
          throw new InvalidKeyException(
159
              "expecting either an RSAPrivateKey or an RSAPublicKey (for blinding)");
160
      }
161
    else
162
      throw new IllegalArgumentException("only encryption and decryption supported");
163
    this.random = random;
164
    this.opmode = opmode;
165
    pos = 0;
166
    dataBuffer = new byte[outputLen];
167
  }
168
 
169
  protected void engineInit(int opmode, Key key, AlgorithmParameterSpec spec,
170
                            SecureRandom random) throws InvalidKeyException
171
  {
172
    engineInit(opmode, key, random);
173
  }
174
 
175
  protected void engineInit(int opmode, Key key, AlgorithmParameters params,
176
                            SecureRandom random) throws InvalidKeyException
177
  {
178
    engineInit(opmode, key, random);
179
  }
180
 
181
  protected byte[] engineUpdate(byte[] in, int offset, int length)
182
  {
183
    if (opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE)
184
      throw new IllegalStateException("not initialized");
185
    System.arraycopy(in, offset, dataBuffer, pos, length);
186
    pos += length;
187
    return EMPTY;
188
  }
189
 
190
  protected int engineUpdate(byte[] in, int offset, int length, byte[] out,
191
                             int outOffset)
192
  {
193
    engineUpdate(in, offset, length);
194
    return 0;
195
  }
196
 
197
  protected byte[] engineDoFinal(byte[] in, int offset, int length)
198
      throws IllegalBlockSizeException, BadPaddingException
199
  {
200
    engineUpdate(in, offset, length);
201
    if (opmode == Cipher.DECRYPT_MODE)
202
      {
203
        BigInteger enc = new BigInteger (1, dataBuffer);
204
        byte[] dec = rsaDecrypt (enc);
205
        logger.log (Component.CRYPTO, "RSA: decryption produced\n{0}",
206
                    new ByteArray (dec));
207
        EME_PKCS1_V1_5 pkcs = EME_PKCS1_V1_5.getInstance(decipherKey);
208
        byte[] result = pkcs.decode(dec);
209
        return result;
210
      }
211
    else
212
      {
213
        offset = dataBuffer.length - pos;
214
        if (offset < 3)
215
          throw new IllegalBlockSizeException("input is too large to encrypt");
216
        EME_PKCS1_V1_5 pkcs = EME_PKCS1_V1_5.getInstance(encipherKey);
217
        if (random == null)
218
          random = new SecureRandom();
219
        byte[] em = new byte[pos];
220
        System.arraycopy(dataBuffer, 0, em, 0, pos);
221
        byte[] dec = pkcs.encode(em, random);
222
        logger.log (Component.CRYPTO, "RSA: produced padded plaintext\n{0}",
223
                    new ByteArray (dec));
224
        BigInteger x = new BigInteger (1, dec);
225
        BigInteger y = x.modPow (encipherKey.getPublicExponent (),
226
                                 encipherKey.getModulus ());
227
        byte[] enc = y.toByteArray ();
228
        if (enc[0] == 0x00)
229
          {
230
            byte[] tmp = new byte[enc.length - 1];
231
            System.arraycopy(enc, 1, tmp, 0, tmp.length);
232
            enc = tmp;
233
          }
234
        pos = 0;
235
        return enc;
236
      }
237
  }
238
 
239
  protected int engineDoFinal(byte[] out, int offset)
240
      throws ShortBufferException, IllegalBlockSizeException,
241
      BadPaddingException
242
  {
243
    byte[] result = engineDoFinal(EMPTY, 0, 0);
244
    if (out.length - offset < result.length)
245
      throw new ShortBufferException("need " + result.length + ", have "
246
                                     + (out.length - offset));
247
    System.arraycopy(result, 0, out, offset, result.length);
248
    return result.length;
249
  }
250
 
251
  protected int engineDoFinal(final byte[] input, final int offset,
252
                              final int length, final byte[] output,
253
                              final int outputOffset)
254
      throws ShortBufferException, IllegalBlockSizeException,
255
      BadPaddingException
256
  {
257
    byte[] result = engineDoFinal(input, offset, length);
258
    if (output.length - outputOffset < result.length)
259
      throw new ShortBufferException("need " + result.length + ", have "
260
                                     + (output.length - outputOffset));
261
    System.arraycopy(result, 0, output, outputOffset, result.length);
262
    return result.length;
263
  }
264
 
265
  /**
266
   * Decrypts the ciphertext, employing RSA blinding if possible.
267
   */
268
  private byte[] rsaDecrypt(BigInteger enc)
269
  {
270
    if (random == null)
271
      random = new SecureRandom();
272
    BigInteger n = decipherKey.getModulus();
273
    BigInteger r = null;
274
    BigInteger pubExp = null;
275
    if (blindingKey != null)
276
      pubExp = blindingKey.getPublicExponent();
277
    if (pubExp != null && (decipherKey instanceof RSAPrivateCrtKey))
278
      pubExp = ((RSAPrivateCrtKey) decipherKey).getPublicExponent();
279
    if (pubExp != null)
280
      {
281
        r = new BigInteger(n.bitLength() - 1, random);
282
        enc = r.modPow(pubExp, n).multiply(enc).mod(n);
283
      }
284
    BigInteger dec = enc.modPow(decipherKey.getPrivateExponent(), n);
285
    if (pubExp != null)
286
      {
287
        dec = dec.multiply (r.modInverse (n)).mod (n);
288
      }
289
 
290
    byte[] decb = dec.toByteArray();
291
    if (decb[0] != 0x00)
292
      {
293
        byte[] b = new byte[decb.length + 1];
294
        System.arraycopy(decb, 0, b, 1, decb.length);
295
        decb = b;
296
      }
297
    return decb;
298
  }
299
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.