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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* OMAC.java --
2
   Copyright (C) 2004, 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.mac;
40
 
41
import gnu.java.security.Configuration;
42
import gnu.java.security.Registry;
43
import gnu.java.security.util.Util;
44
import gnu.javax.crypto.cipher.CipherFactory;
45
import gnu.javax.crypto.cipher.IBlockCipher;
46
import gnu.javax.crypto.mode.IMode;
47
 
48
import java.security.InvalidKeyException;
49
import java.util.Arrays;
50
import java.util.HashMap;
51
import java.util.Map;
52
import java.util.logging.Logger;
53
 
54
/**
55
 * The One-Key CBC MAC, OMAC. This message authentication code is based on a
56
 * block cipher in CBC mode.
57
 * <p>
58
 * References:
59
 * <ol>
60
 * <li>Tetsu Iwata and Kaoru Kurosawa, <i><a
61
 * href="http://crypt.cis.ibaraki.ac.jp/omac/docs/omac.pdf">OMAC: One-Key CBC
62
 * MAC</a></i>.</li>
63
 * </ol>
64
 */
65
public class OMAC
66
    implements IMac
67
{
68
  private static final Logger log = Logger.getLogger(OMAC.class.getName());
69
  private static final byte C1 = (byte) 0x87;
70
  private static final byte C2 = 0x1b;
71
  // Test key for OMAC-AES-128
72
  private static final byte[] KEY0 =
73
      Util.toBytesFromString("2b7e151628aed2a6abf7158809cf4f3c");
74
  // Test MAC for zero-length input.
75
  private static final byte[] DIGEST0 =
76
      Util.toBytesFromString("bb1d6929e95937287fa37d129b756746");
77
  private static Boolean valid;
78
  private final IBlockCipher cipher;
79
  private final String name;
80
  private IMode mode;
81
  private int blockSize;
82
  private int outputSize;
83
  private byte[] Lu, Lu2;
84
  private byte[] M;
85
  private byte[] Y;
86
  private boolean init;
87
  private int index;
88
 
89
  public OMAC(IBlockCipher cipher)
90
  {
91
    this.cipher = cipher;
92
    this.name = "OMAC-" + cipher.name();
93
  }
94
 
95
  public Object clone()
96
  {
97
    return new OMAC(cipher);
98
  }
99
 
100
  public String name()
101
  {
102
    return name;
103
  }
104
 
105
  public int macSize()
106
  {
107
    return outputSize;
108
  }
109
 
110
  public void init(Map attrib) throws InvalidKeyException
111
  {
112
    HashMap attrib2 = new HashMap();
113
    attrib2.put(IBlockCipher.KEY_MATERIAL, attrib.get(MAC_KEY_MATERIAL));
114
    cipher.reset();
115
    cipher.init(attrib2);
116
    blockSize = cipher.currentBlockSize();
117
    Integer os = (Integer) attrib.get(TRUNCATED_SIZE);
118
    if (os != null)
119
      {
120
        outputSize = os.intValue();
121
        if (outputSize < 0 || outputSize > blockSize)
122
          throw new IllegalArgumentException("truncated size out of range");
123
      }
124
    else
125
      outputSize = blockSize;
126
 
127
    byte[] L = new byte[blockSize];
128
    cipher.encryptBlock(L, 0, L, 0);
129
    if (Configuration.DEBUG)
130
      log.fine("L = " + Util.toString(L).toLowerCase());
131
    if (Lu != null)
132
      {
133
        Arrays.fill(Lu, (byte) 0);
134
        if (Lu.length != blockSize)
135
          Lu = new byte[blockSize];
136
      }
137
    else
138
      Lu = new byte[blockSize];
139
    if (Lu2 != null)
140
      {
141
        Arrays.fill(Lu2, (byte) 0);
142
        if (Lu2.length != blockSize)
143
          Lu2 = new byte[blockSize];
144
      }
145
    else
146
      Lu2 = new byte[blockSize];
147
 
148
    boolean msb = (L[0] & 0x80) != 0;
149
    for (int i = 0; i < blockSize; i++)
150
      {
151
        Lu[i] = (byte)(L[i] << 1 & 0xFF);
152
        if (i + 1 < blockSize)
153
          Lu[i] |= (byte)((L[i + 1] & 0x80) >> 7);
154
      }
155
    if (msb)
156
      {
157
        if (blockSize == 16)
158
          Lu[Lu.length - 1] ^= C1;
159
        else if (blockSize == 8)
160
          Lu[Lu.length - 1] ^= C2;
161
        else
162
          throw new IllegalArgumentException("unsupported cipher block size: "
163
                                             + blockSize);
164
      }
165
    if (Configuration.DEBUG)
166
      log.fine("Lu = " + Util.toString(Lu).toLowerCase());
167
    msb = (Lu[0] & 0x80) != 0;
168
    for (int i = 0; i < blockSize; i++)
169
      {
170
        Lu2[i] = (byte)(Lu[i] << 1 & 0xFF);
171
        if (i + 1 < blockSize)
172
          Lu2[i] |= (byte)((Lu[i + 1] & 0x80) >> 7);
173
      }
174
    if (msb)
175
      {
176
        if (blockSize == 16)
177
          Lu2[Lu2.length - 1] ^= C1;
178
        else
179
          Lu2[Lu2.length - 1] ^= C2;
180
      }
181
    if (Configuration.DEBUG)
182
      log.fine("Lu2 = " + Util.toString(Lu2).toLowerCase());
183
    if (M != null)
184
      {
185
        Arrays.fill(M, (byte) 0);
186
        if (M.length != blockSize)
187
          M = new byte[blockSize];
188
      }
189
    else
190
      M = new byte[blockSize];
191
    if (Y != null)
192
      {
193
        Arrays.fill(Y, (byte) 0);
194
        if (Y.length != blockSize)
195
          Y = new byte[blockSize];
196
      }
197
    else
198
      Y = new byte[blockSize];
199
 
200
    index = 0;
201
    init = true;
202
  }
203
 
204
  public void update(byte b)
205
  {
206
    if (! init)
207
      throw new IllegalStateException("not initialized");
208
    if (index == M.length)
209
      {
210
        process();
211
        index = 0;
212
      }
213
    M[index++] = b;
214
  }
215
 
216
  public void update(byte[] buf, int off, int len)
217
  {
218
    if (! init)
219
      throw new IllegalStateException("not initialized");
220
    if (off < 0 || len < 0 || off + len > buf.length)
221
      throw new IndexOutOfBoundsException("size=" + buf.length + "; off=" + off
222
                                          + "; len=" + len);
223
    for (int i = 0; i < len;)
224
      {
225
        if (index == blockSize)
226
          {
227
            process();
228
            index = 0;
229
          }
230
        int count = Math.min(blockSize - index, len - i);
231
        System.arraycopy(buf, off + i, M, index, count);
232
        index += count;
233
        i += count;
234
      }
235
  }
236
 
237
  public byte[] digest()
238
  {
239
    byte[] b = new byte[outputSize];
240
    digest(b, 0);
241
    return b;
242
  }
243
 
244
  public void digest(byte[] out, int off)
245
  {
246
    if (! init)
247
      throw new IllegalStateException("not initialized");
248
    if (off < 0 || off + outputSize > out.length)
249
      throw new IndexOutOfBoundsException("size=" + out.length + "; off=" + off
250
                                          + "; len=" + outputSize);
251
    byte[] T = new byte[blockSize];
252
    byte[] L = Lu;
253
    if (index < blockSize)
254
      {
255
        M[index++] = (byte) 0x80;
256
        while (index < blockSize)
257
          M[index++] = 0;
258
        L = Lu2;
259
      }
260
    for (int i = 0; i < blockSize; i++)
261
      T[i] = (byte)(M[i] ^ Y[i] ^ L[i]);
262
    cipher.encryptBlock(T, 0, T, 0);
263
    System.arraycopy(T, 0, out, off, outputSize);
264
    reset();
265
  }
266
 
267
  public void reset()
268
  {
269
    index = 0;
270
    if (Y != null)
271
      Arrays.fill(Y, (byte) 0);
272
    if (M != null)
273
      Arrays.fill(M, (byte) 0);
274
  }
275
 
276
  public boolean selfTest()
277
  {
278
    OMAC mac = new OMAC(CipherFactory.getInstance(Registry.AES_CIPHER));
279
    mac.reset();
280
    Map attr = new HashMap();
281
    attr.put(MAC_KEY_MATERIAL, KEY0);
282
    byte[] digest = null;
283
    try
284
      {
285
        mac.init(attr);
286
        digest = mac.digest();
287
      }
288
    catch (Exception x)
289
      {
290
        return false;
291
      }
292
    if (digest == null)
293
      return false;
294
    return Arrays.equals(DIGEST0, digest);
295
  }
296
 
297
  private void process()
298
  {
299
    for (int i = 0; i < blockSize; i++)
300
      M[i] = (byte)(M[i] ^ Y[i]);
301
    cipher.encryptBlock(M, 0, Y, 0);
302
  }
303
}

powered by: WebSVN 2.1.0

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