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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* ICMRandomSpi.java --
2
   Copyright (C) 2001, 2002, 2006  Free Software Foundation, Inc.
3
 
4
This file is a 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 of the License, or (at
9
your option) 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; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19
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.prng;
40
 
41
import gnu.java.security.Configuration;
42
import gnu.java.security.Registry;
43
import gnu.java.security.jce.prng.SecureRandomAdapter;
44
import gnu.java.security.prng.LimitReachedException;
45
import gnu.javax.crypto.cipher.IBlockCipher;
46
import gnu.javax.crypto.prng.ICMGenerator;
47
 
48
import java.math.BigInteger;
49
import java.security.SecureRandomSpi;
50
import java.util.HashMap;
51
import java.util.Random;
52
import java.util.logging.Logger;
53
 
54
/**
55
 * An <em>Adapter</em> class around {@link ICMGenerator} to allow using this
56
 * algorithm as a JCE {@link java.security.SecureRandom}.
57
 */
58
public class ICMRandomSpi
59
    extends SecureRandomSpi
60
{
61
  private static final Logger log = Logger.getLogger(ICMRandomSpi.class.getName());
62
  /** Class-wide prng to generate random material for the underlying prng. */
63
  private static final ICMGenerator prng; // blank final
64
  static
65
    {
66
      prng = new ICMGenerator();
67
      resetLocalPRNG();
68
    }
69
 
70
  // error messages
71
  private static final String MSG = "Exception while setting up an "
72
                                    + Registry.ICM_PRNG + " SPI: ";
73
  private static final String RETRY = "Retry...";
74
  private static final String LIMIT_REACHED_MSG = "Limit reached: ";
75
  private static final String RESEED = "Re-seed...";
76
  /** Our underlying prng instance. */
77
  private ICMGenerator adaptee = new ICMGenerator();
78
 
79
  // default 0-arguments constructor
80
 
81
  private static void resetLocalPRNG()
82
  {
83
    if (Configuration.DEBUG)
84
      log.entering(ICMRandomSpi.class.getName(), "resetLocalPRNG");
85
    HashMap attributes = new HashMap();
86
    attributes.put(ICMGenerator.CIPHER, Registry.AES_CIPHER);
87
    byte[] key = new byte[128 / 8]; // AES default key size
88
    Random rand = new Random(System.currentTimeMillis());
89
    rand.nextBytes(key);
90
    attributes.put(IBlockCipher.KEY_MATERIAL, key);
91
    int aesBlockSize = 128 / 8; // AES block size in bytes
92
    byte[] offset = new byte[aesBlockSize];
93
    rand.nextBytes(offset);
94
    attributes.put(ICMGenerator.OFFSET, offset);
95
    int ndxLen = 0; // the segment length
96
    // choose a random value between 1 and aesBlockSize / 2
97
    int limit = aesBlockSize / 2;
98
    while (ndxLen < 1 || ndxLen > limit)
99
      ndxLen = rand.nextInt(limit + 1);
100
    attributes.put(ICMGenerator.SEGMENT_INDEX_LENGTH, Integer.valueOf(ndxLen));
101
    byte[] index = new byte[ndxLen];
102
    rand.nextBytes(index);
103
    attributes.put(ICMGenerator.SEGMENT_INDEX, new BigInteger(1, index));
104
    prng.setup(attributes);
105
    if (Configuration.DEBUG)
106
      log.exiting(ICMRandomSpi.class.getName(), "resetLocalPRNG");
107
  }
108
 
109
  public byte[] engineGenerateSeed(int numBytes)
110
  {
111
    return SecureRandomAdapter.getSeed(numBytes);
112
  }
113
 
114
  public void engineNextBytes(byte[] bytes)
115
  {
116
    if (Configuration.DEBUG)
117
      log.entering(this.getClass().getName(), "engineNextBytes");
118
    if (! adaptee.isInitialised())
119
      this.engineSetSeed(engineGenerateSeed(32));
120
    while (true)
121
      {
122
        try
123
          {
124
            adaptee.nextBytes(bytes, 0, bytes.length);
125
            break;
126
          }
127
        catch (LimitReachedException x)
128
          { // reseed the generator
129
            if (Configuration.DEBUG)
130
              {
131
                log.fine(LIMIT_REACHED_MSG + String.valueOf(x));
132
                log.fine(RESEED);
133
              }
134
            resetLocalPRNG();
135
          }
136
      }
137
    if (Configuration.DEBUG)
138
      log.exiting(this.getClass().getName(), "engineNextBytes");
139
  }
140
 
141
  public void engineSetSeed(byte[] seed)
142
  {
143
    if (Configuration.DEBUG)
144
      log.entering(this.getClass().getName(), "engineSetSeed");
145
    // compute the total number of random bytes required to setup adaptee
146
    int materialLength = 0;
147
    materialLength += 16; // key material size
148
    materialLength += 16; // offset size
149
    materialLength += 8; // index size == half of an AES block
150
    byte[] material = new byte[materialLength];
151
    // use as much as possible bytes from the seed
152
    int materialOffset = 0;
153
    int materialLeft = material.length;
154
    if (seed.length > 0)
155
      { // copy some bytes into key and update indices
156
        int lenToCopy = Math.min(materialLength, seed.length);
157
        System.arraycopy(seed, 0, material, 0, lenToCopy);
158
        materialOffset += lenToCopy;
159
        materialLeft -= lenToCopy;
160
      }
161
    if (materialOffset > 0) // generate the rest
162
      {
163
        while (true)
164
          {
165
            try
166
              {
167
                prng.nextBytes(material, materialOffset, materialLeft);
168
                break;
169
              }
170
            catch (IllegalStateException x)
171
              { // should not happen
172
                throw new InternalError(MSG + String.valueOf(x));
173
              }
174
            catch (LimitReachedException x)
175
              {
176
                if (Configuration.DEBUG)
177
                  {
178
                    log.fine(MSG + String.valueOf(x));
179
                    log.fine(RETRY);
180
                  }
181
              }
182
          }
183
      }
184
    // setup the underlying adaptee instance
185
    HashMap attributes = new HashMap();
186
    // use AES cipher with 128-bit block size
187
    attributes.put(ICMGenerator.CIPHER, Registry.AES_CIPHER);
188
    // use an index the size of quarter of an AES block
189
    attributes.put(ICMGenerator.SEGMENT_INDEX_LENGTH, Integer.valueOf(4));
190
    // specify the key
191
    byte[] key = new byte[16];
192
    System.arraycopy(material, 0, key, 0, 16);
193
    attributes.put(IBlockCipher.KEY_MATERIAL, key);
194
    // specify the offset
195
    byte[] offset = new byte[16];
196
    System.arraycopy(material, 16, offset, 0, 16);
197
    attributes.put(ICMGenerator.OFFSET, offset);
198
    // specify the index
199
    byte[] index = new byte[4];
200
    System.arraycopy(material, 32, index, 0, 4);
201
    attributes.put(ICMGenerator.SEGMENT_INDEX, new BigInteger(1, index));
202
    adaptee.init(attributes);
203
    if (Configuration.DEBUG)
204
      log.exiting(this.getClass().getName(), "engineSetSeed");
205
  }
206
}

powered by: WebSVN 2.1.0

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