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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* KeyWrappingAlgorithmAdapter.java -- Base Adapter for Key Wrapping algorithms
2
   Copyright (C) 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.jce.cipher;
40
 
41
import gnu.java.security.Configuration;
42
import gnu.java.security.Registry;
43
import gnu.javax.crypto.jce.spec.BlockCipherParameterSpec;
44
import gnu.javax.crypto.kwa.IKeyWrappingAlgorithm;
45
import gnu.javax.crypto.kwa.KeyUnwrappingException;
46
import gnu.javax.crypto.kwa.KeyWrappingAlgorithmFactory;
47
 
48
import java.security.AlgorithmParameters;
49
import java.security.InvalidAlgorithmParameterException;
50
import java.security.InvalidKeyException;
51
import java.security.Key;
52
import java.security.KeyFactory;
53
import java.security.NoSuchAlgorithmException;
54
import java.security.SecureRandom;
55
import java.security.spec.AlgorithmParameterSpec;
56
import java.security.spec.InvalidKeySpecException;
57
import java.security.spec.InvalidParameterSpecException;
58
import java.security.spec.X509EncodedKeySpec;
59
import java.util.HashMap;
60
import java.util.Map;
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
import javax.crypto.spec.IvParameterSpec;
70
import javax.crypto.spec.SecretKeySpec;
71
 
72
/**
73
 * An abstract base class to facilitate implementations of JCE Adapters for
74
 * symmetric key block ciphers capable of providing key-wrapping functionality.
75
 */
76
abstract class KeyWrappingAlgorithmAdapter
77
    extends CipherSpi
78
{
79
  private static final Logger log = Logger.getLogger(KeyWrappingAlgorithmAdapter.class.getName());
80
  /** JCE canonical name of a null-padder. */
81
  private static final String NO_PADDING = "nopadding";
82
  /** Concrete Key Wrapping Algorithm SPI. */
83
  protected IKeyWrappingAlgorithm kwAlgorithm;
84
  /** Size in bytes of the padding block to be provided by external padders. */
85
  protected int kwaBlockSize;
86
  /** KEK size in bytes. */
87
  protected int kwaKeySize;
88
  /** Name of the supported mode. */
89
  protected String supportedMode;
90
  /** Operational mode in which this instance was initialised. */
91
  protected int opmode = -1;
92
  /** Initialisation Vector if/when user wants to override default one. */
93
  byte[] iv;
94
 
95
  /**
96
   * Creates a new JCE Adapter for the designated Key Wrapping Algorithm name.
97
   *
98
   * @param name the canonical name of the key-wrapping algorithm.
99
   * @param blockSize the block size in bytes of the underlying symmetric-key
100
   *          block cipher algorithm.
101
   * @param keySize the allowed size in bytes of the KEK bytes to initialise the
102
   *          underlying symmetric-key block cipher algorithm with.
103
   * @param supportedMode canonical name of the block mode the underlying cipher
104
   *          is supporting.
105
   */
106
  protected KeyWrappingAlgorithmAdapter(String name, int blockSize, int keySize,
107
                                        String supportedMode)
108
  {
109
    super();
110
 
111
    this.kwAlgorithm = KeyWrappingAlgorithmFactory.getInstance(name);
112
    this.kwaBlockSize = blockSize;
113
    this.kwaKeySize = keySize;
114
    this.supportedMode = supportedMode;
115
  }
116
 
117
  /**
118
   * Wraps the encoded form of a designated {@link Key}.
119
   *
120
   * @param key the key-material to wrap.
121
   * @return the wrapped key.
122
   * @throws InvalidKeyException If the key cannot be wrapped.
123
   */
124
  protected byte[] engineWrap(Key key)
125
      throws InvalidKeyException, IllegalBlockSizeException
126
  {
127
    byte[] keyMaterial = key.getEncoded();
128
    byte[] result = kwAlgorithm.wrap(keyMaterial, 0, keyMaterial.length);
129
    return result;
130
  }
131
 
132
  /**
133
   * Unwraps a previously-wrapped key-material.
134
   *
135
   * @param wrappedKey the wrapped key-material to unwrap.
136
   * @param wrappedKeyAlgorithm the canonical name of the algorithm, which the
137
   *          unwrapped key-material represents. This name is used to
138
   *          instantiate a concrete instance of a {@link Key} for that
139
   *          algorithm. For example, if the value of this parameter is
140
   *          <code>DSS</code> and the type (the next parameter) is
141
   *          {@link Cipher#PUBLIC_KEY} then an attempt to construct a concrete
142
   *          instance of a {@link java.security.interfaces.DSAPublicKey},
143
   *          using the unwrapped key material, shall be made.
144
   * @param wrappedKeyType the type of wrapped key-material. MUST be one of
145
   *          {@link Cipher#PRIVATE_KEY}, {@link Cipher#PUBLIC_KEY}, or
146
   *          {@link Cipher#SECRET_KEY}.
147
   * @return the unwrapped key-material as an instance of {@link Key} or one of
148
   *         its subclasses.
149
   * @throws InvalidKeyException If the key cannot be unwrapped, or if
150
   *           <code>wrappedKeyType</code> is an inappropriate type for the
151
   *           unwrapped key.
152
   * @throws NoSuchAlgorithmException If the <code>wrappedKeyAlgorithm</code>
153
   *           is unknown to every currently installed Security Provider.
154
   */
155
  protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
156
                             int wrappedKeyType)
157
      throws InvalidKeyException, NoSuchAlgorithmException
158
  {
159
    byte[] keyBytes;
160
    try
161
      {
162
        keyBytes = kwAlgorithm.unwrap(wrappedKey, 0, wrappedKey.length);
163
      }
164
    catch (KeyUnwrappingException x)
165
      {
166
        InvalidKeyException y = new InvalidKeyException("engineUnwrap()");
167
        y.initCause(x);
168
        throw y;
169
      }
170
    Key result;
171
    switch (wrappedKeyType)
172
      {
173
      case Cipher.SECRET_KEY:
174
        result = new SecretKeySpec(keyBytes, wrappedKeyAlgorithm);
175
        break;
176
      case Cipher.PRIVATE_KEY:
177
      case Cipher.PUBLIC_KEY:
178
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
179
        KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
180
        try
181
          {
182
            if (wrappedKeyType == Cipher.PRIVATE_KEY)
183
              result = keyFactory.generatePrivate(keySpec);
184
            else
185
              result = keyFactory.generatePublic(keySpec);
186
          }
187
        catch (InvalidKeySpecException x)
188
          {
189
            InvalidKeyException y = new InvalidKeyException("engineUnwrap()");
190
            y.initCause(x);
191
            throw y;
192
          }
193
        break;
194
      default:
195
        IllegalArgumentException x = new IllegalArgumentException("Invalid 'wrappedKeyType': "
196
                                                                  + wrappedKeyType);
197
        InvalidKeyException y = new InvalidKeyException("engineUnwrap()");
198
        y.initCause(x);
199
        throw y;
200
      }
201
    return result;
202
  }
203
 
204
  protected int engineGetBlockSize()
205
  {
206
    return kwaBlockSize;
207
  }
208
 
209
  protected byte[] engineGetIV()
210
  {
211
    return iv == null ? null : (byte[]) iv.clone();
212
  }
213
 
214
  protected int engineGetOutputSize(int inputLength)
215
  {
216
    switch (opmode)
217
    {
218
      case Cipher.WRAP_MODE:
219
        return getOutputSizeForWrap(inputLength);
220
      case Cipher.UNWRAP_MODE:
221
        return getOutputSizeForUnwrap(inputLength);
222
      default:
223
        throw new IllegalStateException();
224
    }
225
  }
226
 
227
  protected AlgorithmParameters engineGetParameters()
228
  {
229
    BlockCipherParameterSpec spec = new BlockCipherParameterSpec(iv,
230
                                                                 kwaBlockSize,
231
                                                                 kwaKeySize);
232
    AlgorithmParameters result = null;
233
    try
234
      {
235
        result = AlgorithmParameters.getInstance("BlockCipherParameters");
236
        result.init(spec);
237
      }
238
    catch (NoSuchAlgorithmException x)
239
      {
240
        if (Configuration.DEBUG)
241
          log.fine("Unable to find BlockCipherParameters. Return null");
242
      }
243
    catch (InvalidParameterSpecException x)
244
      {
245
        if (Configuration.DEBUG)
246
          log.fine("Unable to initialise BlockCipherParameters. Return null");
247
      }
248
    return result;
249
  }
250
 
251
  protected void engineInit(int opmode, Key key, SecureRandom random)
252
      throws InvalidKeyException
253
  {
254
    checkOpMode(opmode);
255
    byte[] kekBytes = checkAndGetKekBytes(key);
256
    initAlgorithm(opmode, kekBytes, null, random);
257
  }
258
 
259
  protected void engineInit(int opmode, Key key, AlgorithmParameters params,
260
                            SecureRandom random)
261
      throws InvalidAlgorithmParameterException, InvalidKeyException
262
  {
263
    AlgorithmParameterSpec spec = null;
264
    try
265
      {
266
        if (params != null)
267
          spec = params.getParameterSpec(BlockCipherParameterSpec.class);
268
      }
269
    catch (InvalidParameterSpecException x)
270
      {
271
        if (Configuration.DEBUG)
272
          log.fine("Unable to translate algorithm parameters into an instance "
273
                   + "of BlockCipherParameterSpec. Discard");
274
      }
275
    engineInit(opmode, key, spec, random);
276
  }
277
 
278
  protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
279
                            SecureRandom random)
280
      throws InvalidAlgorithmParameterException, InvalidKeyException
281
  {
282
    checkOpMode(opmode);
283
    byte[] kekBytes = checkAndGetKekBytes(key);
284
    byte[] ivBytes = null;
285
    if (params instanceof BlockCipherParameterSpec)
286
      ivBytes = ((BlockCipherParameterSpec) params).getIV();
287
    else if (params instanceof IvParameterSpec)
288
      ivBytes = ((IvParameterSpec) params).getIV();
289
 
290
    initAlgorithm(opmode, kekBytes, ivBytes, random);
291
  }
292
 
293
  protected void engineSetMode(String mode) throws NoSuchAlgorithmException
294
  {
295
    if (! supportedMode.equalsIgnoreCase(mode))
296
      throw new UnsupportedOperationException("Only " + supportedMode
297
                                              + " is supported");
298
  }
299
 
300
  /**
301
   * NoPadding is the only padding algorithm supported by Key Wrapping Algorithm
302
   * implementations in RI.
303
   */
304
  protected void engineSetPadding(String padding) throws NoSuchPaddingException
305
  {
306
    if (! NO_PADDING.equalsIgnoreCase(padding))
307
      throw new UnsupportedOperationException("Only NoPadding is supported");
308
  }
309
 
310
  protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLength)
311
  {
312
    throw new UnsupportedOperationException();
313
  }
314
 
315
  protected int engineUpdate(byte[] input, int inputOffset, int inputLength,
316
                             byte[] output, int outputOffset)
317
      throws ShortBufferException
318
  {
319
    throw new UnsupportedOperationException();
320
  }
321
 
322
  protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLength)
323
      throws IllegalBlockSizeException, BadPaddingException
324
  {
325
    throw new UnsupportedOperationException();
326
  }
327
 
328
  protected int engineDoFinal(byte[] input, int inputOffset, int inputLength,
329
                              byte[] output, int outputOffset)
330
      throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
331
  {
332
    throw new UnsupportedOperationException();
333
  }
334
 
335
  /**
336
   * Return the minimum size in bytes of a place holder large enough to receive
337
   * the cipher text resulting from a wrap method with the designated size of
338
   * the plain text.
339
   * <p>
340
   * This default implementation ALWAYS returns the smallest multiple of the
341
   * <code>kwaBlockSize</code> --passed to this method through its
342
   * constructor-- greater than or equal to the designated
343
   * <code>inputLength</code>.
344
   *
345
   * @param inputLength the size of a plain text.
346
   * @return an estimate of the size, in bytes, of the place holder to receive
347
   * the resulting bytes of a wrap method.
348
   */
349
  protected int getOutputSizeForWrap(int inputLength)
350
  {
351
    return kwaBlockSize * (inputLength + kwaBlockSize - 1) / kwaBlockSize;
352
  }
353
 
354
  /**
355
   * Return the minimum size in bytes of a place holder large enough to receive
356
   * the plain text resulting from an unwrap method with the designated size of
357
   * the cipher text.
358
   * <p>
359
   * This default implementation ALWAYS returns the smallest multiple of the
360
   * <code>paddingBlockSize</code> --passed to this method through its
361
   * constructor-- greater than or equal to the designated
362
   * <code>inputLength</code>.
363
   *
364
   * @param inputLength the size of a cipher text.
365
   * @return an estimate of the size, in bytes, of the place holder to receive
366
   *         the resulting bytes of an uwrap method.
367
   */
368
  protected int getOutputSizeForUnwrap(int inputLength)
369
  {
370
    return kwaBlockSize * (inputLength + kwaBlockSize - 1) / kwaBlockSize;
371
  }
372
 
373
  private void checkOpMode(int opmode)
374
  {
375
    switch (opmode)
376
    {
377
      case Cipher.WRAP_MODE:
378
      case Cipher.UNWRAP_MODE:
379
        return;
380
    }
381
    throw new IllegalArgumentException("Unsupported operational mode: " + opmode);
382
  }
383
 
384
  /**
385
   * Returns the key bytes, iff it was in RAW format.
386
   *
387
   * @param key the opaque JCE secret key to use as the KEK.
388
   * @return the bytes of the encoded form of the designated kek, iff it was in
389
   *         RAW format.
390
   * @throws InvalidKeyException if the designated key is not in the RAW format.
391
   */
392
  private byte[] checkAndGetKekBytes(Key key) throws InvalidKeyException
393
  {
394
    if (! Registry.RAW_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat()))
395
      throw new InvalidKeyException("Only RAW key format is supported");
396
    byte[] result = key.getEncoded();
397
    int kekSize = result.length;
398
    if (kekSize != kwaKeySize)
399
      throw new InvalidKeyException("Invalid key material size. Expected "
400
                                    + kwaKeySize + " but found " + kekSize);
401
    return result;
402
  }
403
 
404
  private void initAlgorithm(int opmode, byte[] kek, byte[] ivBytes,
405
                             SecureRandom rnd)
406
      throws InvalidKeyException
407
  {
408
    this.opmode = opmode;
409
    Map attributes = new HashMap();
410
    attributes.put(IKeyWrappingAlgorithm.KEY_ENCRYPTION_KEY_MATERIAL, kek);
411
    if (ivBytes != null)
412
      {
413
        this.iv = (byte[]) ivBytes.clone();
414
        attributes.put(IKeyWrappingAlgorithm.INITIAL_VALUE, this.iv);
415
      }
416
    else
417
      this.iv = null;
418
    if (rnd != null)
419
      attributes.put(IKeyWrappingAlgorithm.SOURCE_OF_RANDOMNESS, rnd);
420
 
421
    kwAlgorithm.init(attributes);
422
  }
423
}

powered by: WebSVN 2.1.0

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