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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [javax/] [crypto/] [RSACipherImpl.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* DiffieHellmanImpl.java -- implementation of the Diffie-Hellman key agreement.
2
   Copyright (C) 2005  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.ByteArray;
42
import gnu.classpath.debug.Component;
43
import gnu.classpath.debug.SystemLogger;
44
 
45
import java.math.BigInteger;
46
 
47
import java.security.AlgorithmParameters;
48
import java.security.InvalidAlgorithmParameterException;
49
import java.security.InvalidKeyException;
50
import java.security.Key;
51
import java.security.NoSuchAlgorithmException;
52
import java.security.SecureRandom;
53
 
54
import java.security.interfaces.RSAKey;
55
import java.security.interfaces.RSAPrivateKey;
56
import java.security.interfaces.RSAPrivateCrtKey;
57
import java.security.interfaces.RSAPublicKey;
58
 
59
import java.security.spec.AlgorithmParameterSpec;
60
 
61
import java.util.logging.Logger;
62
 
63
import javax.crypto.BadPaddingException;
64
import javax.crypto.Cipher;
65
import javax.crypto.CipherSpi;
66
import javax.crypto.IllegalBlockSizeException;
67
import javax.crypto.NoSuchPaddingException;
68
import javax.crypto.ShortBufferException;
69
 
70
public class RSACipherImpl extends CipherSpi
71
{
72
  private static final Logger logger = SystemLogger.SYSTEM;
73
 
74
  private static final byte[] EMPTY = new byte[0];
75
  private int opmode = -1;
76
  private RSAPrivateKey decipherKey = null;
77
  private RSAPublicKey blindingKey = null;
78
  private RSAPublicKey encipherKey = null;
79
  private SecureRandom random = null;
80
  private byte[] dataBuffer = null;
81
  private int pos = 0;
82
 
83
  protected void engineSetMode (String mode) throws NoSuchAlgorithmException
84
  {
85
    throw new NoSuchAlgorithmException ("only one mode available");
86
  }
87
 
88
  protected void engineSetPadding (String pad) throws NoSuchPaddingException
89
  {
90
    throw new NoSuchPaddingException ("only one padding available");
91
  }
92
 
93
  protected int engineGetBlockSize ()
94
  {
95
    return 1;
96
  }
97
 
98
  protected int engineGetOutputSize (int inputLen)
99
  {
100
    int outputLen = 0;
101
    if (decipherKey != null)
102
      {
103
        outputLen = (decipherKey.getModulus ().bitLength () + 7) / 8;
104
      }
105
    else if (encipherKey != null)
106
      {
107
        outputLen = (encipherKey.getModulus ().bitLength () + 7) / 8;
108
      }
109
    else
110
      throw new IllegalStateException ("not initialized");
111
    if (inputLen > outputLen)
112
      throw new IllegalArgumentException ("not configured to encode " + inputLen
113
                                          + "bytes; at most " + outputLen);
114
    return outputLen;
115
  }
116
 
117
  protected int engineGetKeySize (final Key key) throws InvalidKeyException
118
  {
119
    if (!(key instanceof RSAKey))
120
      throw new InvalidKeyException ("not an RSA key");
121
    return ((RSAKey) key).getModulus ().bitLength ();
122
  }
123
 
124
  protected byte[] engineGetIV ()
125
  {
126
    return null;
127
  }
128
 
129
  protected AlgorithmParameters engineGetParameters()
130
  {
131
    return null;
132
  }
133
 
134
  protected void engineInit (int opmode, Key key, SecureRandom random)
135
    throws InvalidKeyException
136
  {
137
    int outputLen = 0;
138
    if (opmode == Cipher.ENCRYPT_MODE)
139
      {
140
        if (!(key instanceof RSAPublicKey))
141
          throw new InvalidKeyException ("expecting a RSAPublicKey");
142
        encipherKey = (RSAPublicKey) key;
143
        decipherKey = null;
144
        blindingKey = null;
145
        outputLen = (encipherKey.getModulus ().bitLength () + 7) / 8;
146
      }
147
    else if (opmode == Cipher.DECRYPT_MODE)
148
      {
149
        if (key instanceof RSAPrivateKey)
150
          {
151
            decipherKey = (RSAPrivateKey) key;
152
            encipherKey = null;
153
            blindingKey = null;
154
            outputLen = (decipherKey.getModulus ().bitLength () + 7) / 8;
155
          }
156
        else if (key instanceof RSAPublicKey)
157
          {
158
            if (decipherKey == null)
159
              throw new IllegalStateException ("must configure decryption key first");
160
            if (!decipherKey.getModulus ().equals (((RSAPublicKey) key).getModulus ()))
161
              throw new InvalidKeyException ("blinding key is not compatible");
162
            blindingKey = (RSAPublicKey) key;
163
            return;
164
          }
165
        else
166
          throw new InvalidKeyException ("expecting either an RSAPrivateKey or an RSAPublicKey (for blinding)");
167
      }
168
    else
169
      throw new IllegalArgumentException ("only encryption and decryption supported");
170
    this.random = random;
171
    this.opmode = opmode;
172
    pos = 0;
173
    dataBuffer = new byte[outputLen];
174
  }
175
 
176
  protected void engineInit (int opmode, Key key, AlgorithmParameterSpec spec, SecureRandom random)
177
    throws InvalidKeyException
178
  {
179
    engineInit (opmode, key, random);
180
  }
181
 
182
  protected void engineInit (int opmode, Key key, AlgorithmParameters params, SecureRandom random)
183
    throws InvalidKeyException
184
  {
185
    engineInit (opmode, key, random);
186
  }
187
 
188
  protected byte[] engineUpdate (byte[] in, int offset, int length)
189
  {
190
    if (opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE)
191
      throw new IllegalStateException ("not initialized");
192
    System.arraycopy (in, offset, dataBuffer, pos, length);
193
    pos += length;
194
    return EMPTY;
195
  }
196
 
197
  protected int engineUpdate (byte[] in, int offset, int length, byte[] out, int outOffset)
198
  {
199
    engineUpdate (in, offset, length);
200
    return 0;
201
  }
202
 
203
  protected byte[] engineDoFinal (byte[] in, int offset, int length)
204
    throws IllegalBlockSizeException, BadPaddingException
205
  {
206
    engineUpdate (in, offset, length);
207
    if (opmode == Cipher.DECRYPT_MODE)
208
      {
209
        if (pos < dataBuffer.length)
210
          throw new IllegalBlockSizeException ("expecting exactly " + dataBuffer.length + " bytes");
211
        BigInteger enc = new BigInteger (1, dataBuffer);
212
        byte[] dec = rsaDecrypt (enc);
213
        logger.log (Component.CRYPTO, "RSA: decryption produced\n{0}",
214
                    new ByteArray (dec));
215
        if (dec[0] != 0x02)
216
          throw new BadPaddingException ("expected padding type 2");
217
        int i;
218
        for (i = 1; i < dec.length && dec[i] != 0x00; i++);
219
        int len = dec.length - i;
220
        byte[] result = new byte[len];
221
        System.arraycopy (dec, i, result, 0, len);
222
        pos = 0;
223
        return result;
224
      }
225
    else
226
      {
227
        offset = dataBuffer.length - pos;
228
        if (offset < 3)
229
          throw new IllegalBlockSizeException ("input is too large to encrypt");
230
        byte[] dec = new byte[dataBuffer.length];
231
        dec[0] = 0x02;
232
        if (random == null)
233
          random = new SecureRandom ();
234
        byte[] pad = new byte[offset - 2];
235
        random.nextBytes (pad);
236
        for (int i = 0; i < pad.length; i++)
237
          if (pad[i] == 0)
238
            pad[i] = 1;
239
        System.arraycopy (pad, 0, dec, 1, pad.length);
240
        dec[dec.length - pos] = 0x00;
241
        System.arraycopy (dataBuffer, 0, dec, offset, pos);
242
        logger.log (Component.CRYPTO, "RSA: produced padded plaintext\n{0}",
243
                    new ByteArray (dec));
244
        BigInteger x = new BigInteger (1, dec);
245
        BigInteger y = x.modPow (encipherKey.getPublicExponent (),
246
                                 encipherKey.getModulus ());
247
        byte[] enc = y.toByteArray ();
248
        if (enc[0] == 0x00)
249
          {
250
            byte[] tmp = new byte[enc.length - 1];
251
            System.arraycopy (enc, 1, tmp, 0, tmp.length);
252
            enc = tmp;
253
          }
254
        pos = 0;
255
        return enc;
256
      }
257
  }
258
 
259
  protected int engineDoFinal (byte[] out, int offset)
260
    throws ShortBufferException, IllegalBlockSizeException, BadPaddingException
261
  {
262
    byte[] result = engineDoFinal (EMPTY, 0, 0);
263
    if (out.length - offset < result.length)
264
      throw new ShortBufferException ("need " + result.length + ", have "
265
                                      + (out.length - offset));
266
    System.arraycopy (result, 0, out, offset, result.length);
267
    return result.length;
268
  }
269
 
270
  protected int engineDoFinal (final byte[] input, final int offset, final int length,
271
                               final byte[] output, final int outputOffset)
272
    throws ShortBufferException, IllegalBlockSizeException, BadPaddingException
273
  {
274
    byte[] result = engineDoFinal (input, offset, length);
275
    if (output.length - outputOffset < result.length)
276
      throw new ShortBufferException ("need " + result.length + ", have "
277
                                      + (output.length - outputOffset));
278
    System.arraycopy (result, 0, output, outputOffset, result.length);
279
    return result.length;
280
  }
281
 
282
  /**
283
   * Decrypts the ciphertext, employing RSA blinding if possible.
284
   */
285
  private byte[] rsaDecrypt (BigInteger enc)
286
  {
287
    if (random == null)
288
      random = new SecureRandom ();
289
    BigInteger n = decipherKey.getModulus ();
290
    BigInteger r = null;
291
    BigInteger pubExp = null;
292
    if (blindingKey != null)
293
      pubExp = blindingKey.getPublicExponent ();
294
    if (pubExp != null && (decipherKey instanceof RSAPrivateCrtKey))
295
      pubExp = ((RSAPrivateCrtKey) decipherKey).getPublicExponent ();
296
    if (pubExp != null)
297
      {
298
        r = new BigInteger (n.bitLength () - 1, random);
299
        enc = r.modPow (pubExp, n).multiply (enc).mod (n);
300
      }
301
 
302
    BigInteger dec = enc.modPow (decipherKey.getPrivateExponent (), n);
303
 
304
    if (pubExp != null)
305
      {
306
        dec = dec.multiply (r.modInverse (n)).mod (n);
307
      }
308
 
309
    return dec.toByteArray ();
310
  }
311
}

powered by: WebSVN 2.1.0

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