Frames | No Frames |
1: /* KDF.java -- 2: Copyright (C) 2003, 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.sasl.srp; 40: 41: import gnu.java.security.Registry; 42: import gnu.java.security.prng.LimitReachedException; 43: import gnu.java.security.util.PRNG; 44: import gnu.javax.crypto.cipher.IBlockCipher; 45: import gnu.javax.crypto.prng.UMacGenerator; 46: 47: import java.util.HashMap; 48: 49: /** 50: * The SASL-SRP KDF implementation, which is also used, depending on how it was 51: * instantiated, as a secure Pseudo Random Number Generator. 52: */ 53: public class KDF 54: { 55: private static final int AES_BLOCK_SIZE = 16; // default block size for AES 56: private static final int AES_KEY_SIZE = 16; // default key size for the AES 57: private static final byte[] buffer = new byte[1]; 58: /** Our default source of randomness. */ 59: private static final PRNG prng = PRNG.getInstance(); 60: /** The underlying UMAC Generator instance. */ 61: private UMacGenerator umac = null; 62: 63: /** 64: * Constructs an instance of the <code>KDF</code> initialised with the 65: * designated shared secret bytes. 66: * 67: * @param keyMaterial the SASL SRP shared secret (K) bytes. 68: */ 69: private KDF(final byte[] keyMaterial, final int ndx) 70: { 71: super(); 72: 73: final HashMap map = new HashMap(); 74: map.put(UMacGenerator.CIPHER, Registry.AES_CIPHER); 75: map.put(UMacGenerator.INDEX, Integer.valueOf(ndx)); 76: map.put(IBlockCipher.CIPHER_BLOCK_SIZE, Integer.valueOf(AES_BLOCK_SIZE)); 77: final byte[] key = new byte[AES_KEY_SIZE]; 78: System.arraycopy(keyMaterial, 0, key, 0, AES_KEY_SIZE); 79: map.put(IBlockCipher.KEY_MATERIAL, key); 80: umac = new UMacGenerator(); 81: umac.init(map); 82: } 83: 84: /** 85: * A Factory mehod that returns an instance of a <code>KDF</code> based on 86: * supplied seed data. 87: * 88: * @param K the SASL SRP shared secret for a <code>KDF</code> to be used for 89: * <i>CALG</i> and <i>IALG</i> setup. <code>null</code> otherwise. 90: * @return an instance of a <code>KDF</code>. 91: */ 92: static final KDF getInstance(final byte[] K) 93: { 94: int ndx = -1; 95: final byte[] keyMaterial; 96: if (K != null) 97: { 98: keyMaterial = K; 99: ndx = 0; 100: } 101: else 102: { 103: keyMaterial = new byte[AES_BLOCK_SIZE]; 104: while (ndx < 1 || ndx > 255) 105: ndx = (byte) nextByte(); 106: } 107: return new KDF(keyMaterial, ndx); 108: } 109: 110: private static synchronized final int nextByte() 111: { 112: prng.nextBytes(buffer); 113: return (buffer[0] & 0xFF); 114: } 115: 116: /** 117: * Returns a designated number of bytes suitable for use in the SASL SRP 118: * mechanism. 119: * 120: * @param length the number of bytes needed. 121: * @return a byte array containing the generated/selected bytes. 122: */ 123: public synchronized byte[] derive(final int length) 124: { 125: final byte[] result = new byte[length]; 126: try 127: { 128: umac.nextBytes(result, 0, length); 129: } 130: catch (IllegalStateException x) // should not happen 131: { 132: x.printStackTrace(System.err); 133: } 134: catch (LimitReachedException x) // idem 135: { 136: x.printStackTrace(System.err); 137: } 138: return result; 139: } 140: }