1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.apache.harmony.security.provider.crypto; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.InvalidParameterException; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.SecureRandomSpi; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.security.internal.nls.Messages; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.security.provider.crypto.RandomBitsSupplier; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.security.provider.crypto.SHA1Impl; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.Serializable; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ObjectInputStream; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ObjectOutputStream; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class extends the SecureRandomSpi class implementing all its abstract methods. <BR> 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <BR> 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * To generate pseudo-random bits, the implementation uses technique described in 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the "Random Number Generator (RNG) algorithms" section, Appendix A, 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JavaTM Cryptography Architecture, API Specification&Reference <BR> 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <BR> 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The class implements the Serializable interface. 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class SHA1PRNG_SecureRandomImpl extends SecureRandomSpi implements 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Serializable, SHA1_Data { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final long serialVersionUID = 283736797212159675L; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // constants to use in expressions operating on bytes in int and long variables: 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END_FLAGS - final bytes in words to append to message; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // see "ch.5.1 Padding the Message, FIPS 180-2" 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // RIGHT1 - shifts to right for left half of long 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // RIGHT2 - shifts to right for right half of long 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // LEFT - shifts to left for bytes 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // MASK - mask to select counter's bytes after shift to right 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int[] END_FLAGS = { 0x80000000, 0x800000, 0x8000, 0x80 }; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int[] RIGHT1 = { 0, 40, 48, 56 }; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int[] RIGHT2 = { 0, 8, 16, 24 }; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int[] LEFT = { 0, 24, 16, 8 }; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int[] MASK = { 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 0x000000FF }; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // HASHBYTES_TO_USE defines # of bytes returned by "computeHash(byte[])" 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // to use to form byte array returning by the "nextBytes(byte[])" method 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Note, that this implementation uses more bytes than it is defined 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // in the above specification. 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int HASHBYTES_TO_USE = 20; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // value of 16 defined in the "SECURE HASH STANDARD", FIPS PUB 180-2 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int FRAME_LENGTH = 16; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // miscellaneous constants defined in this implementation: 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // COUNTER_BASE - initial value to set to "counter" before computing "nextBytes(..)"; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // note, that the exact value is not defined in STANDARD 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // HASHCOPY_OFFSET - offset for copy of current hash in "copies" array 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // EXTRAFRAME_OFFSET - offset for extra frame in "copies" array; 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // as the extra frame follows the current hash frame, 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // EXTRAFRAME_OFFSET is equal to length of current hash frame 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // FRAME_OFFSET - offset for frame in "copies" array 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // MAX_BYTES - maximum # of seed bytes processing which doesn't require extra frame 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // see (1) comments on usage of "seed" array below and 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // (2) comments in "engineNextBytes(byte[])" method 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // UNDEFINED - three states of engine; initially its state is "UNDEFINED" 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // SET_SEED call to "engineSetSeed" sets up "SET_SEED" state, 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // NEXT_BYTES call to "engineNextByte" sets up "NEXT_BYTES" state 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int COUNTER_BASE = 0; 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int HASHCOPY_OFFSET = 0; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int EXTRAFRAME_OFFSET = 5; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int FRAME_OFFSET = 21; 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int MAX_BYTES = 48; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int UNDEFINED = 0; 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int SET_SEED = 1; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final int NEXT_BYTES = 2; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static SHA1PRNG_SecureRandomImpl myRandom; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Structure of "seed" array: 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - 0-79 - words for computing hash 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - 80 - unused 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - 81 - # of seed bytes in current seed frame 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - 82-86 - 5 words, current seed hash 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private transient int seed[]; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // total length of seed bytes, including all processed 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private transient long seedLength; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Structure of "copies" array 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - 0-4 - 5 words, copy of current seed hash 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - 5-20 - extra 16 words frame; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // is used if final padding exceeds 512-bit length 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - 21-36 - 16 word frame to store a copy of remaining bytes 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private transient int copies[]; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // ready "next" bytes; needed because words are returned 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private transient byte nextBytes[]; 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // index of used bytes in "nextBytes" array 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private transient int nextBIndex; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // variable required according to "SECURE HASH STANDARD" 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private transient long counter; 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // contains int value corresponding to engine's current state 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private transient int state; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The "seed" array is used to compute both "current seed hash" and "next bytes". 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // As the "SHA1" algorithm computes a hash of entire seed by splitting it into 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // a number of the 512-bit length frames (512 bits = 64 bytes = 16 words), 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // "current seed hash" is a hash (5 words, 20 bytes) for all previous full frames; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // remaining bytes are stored in the 0-15 word frame of the "seed" array. 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // As for calculating "next bytes", 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // both remaining bytes and "current seed hash" are used, 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // to preserve the latter for following "setSeed(..)" commands, 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the following technique is used: 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - upon getting "nextBytes(byte[])" invoked, single or first in row, 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // which requires computing new hash, that is, 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // there is no more bytes remaining from previous "next bytes" computation, 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // remaining bytes are copied into the 21-36 word frame of the "copies" array; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // - upon getting "setSeed(byte[])" invoked, single or first in row, 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // remaining bytes are copied back. 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Creates object and sets implementation variables to their initial values 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public SHA1PRNG_SecureRandomImpl() { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed = new int[HASH_OFFSET + EXTRAFRAME_OFFSET]; 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[HASH_OFFSET] = H0; 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[HASH_OFFSET + 1] = H1; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[HASH_OFFSET + 2] = H2; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[HASH_OFFSET + 3] = H3; 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[HASH_OFFSET + 4] = H4; 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seedLength = 0; 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copies = new int[2 * FRAME_LENGTH + EXTRAFRAME_OFFSET]; 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBytes = new byte[DIGEST_LENGTH]; 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBIndex = HASHBYTES_TO_USE; 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project counter = COUNTER_BASE; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = UNDEFINED; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The method invokes the SHA1Impl's "updateHash(..)" method 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to update current seed frame and 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to compute new intermediate hash value if the frame is full. 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * After that it computes a length of whole seed. 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void updateSeed(byte[] bytes) { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // on call: "seed" contains current bytes and current hash; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // on return: "seed" contains new current bytes and possibly new current hash 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // if after adding, seed bytes overfill its buffer 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SHA1Impl.updateHash(seed, bytes, 0, bytes.length - 1); 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seedLength += bytes.length; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Changes current seed by supplementing a seed argument to the current seed, 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if this already set; 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the argument is used as first seed otherwise. <BR> 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The method overrides "engineSetSeed(byte[])" in class SecureRandomSpi. 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * seed - byte array 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NullPointerException - if null is passed to the "seed" argument 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void engineSetSeed(byte[] seed) { 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (seed == null) { 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException( 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Messages.getString("security.83", "seed")); //$NON-NLS-1$ //$NON-NLS-2$ 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (state == NEXT_BYTES) { // first setSeed after NextBytes; restoring hash 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(copies, HASHCOPY_OFFSET, this.seed, HASH_OFFSET, 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXTRAFRAME_OFFSET); 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = SET_SEED; 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (seed.length != 0) { 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateSeed(seed); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a required number of random bytes. <BR> 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The method overrides "engineGenerateSeed (int)" in class SecureRandomSpi. <BR> 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * numBytes - number of bytes to return; should be >= 0. 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * byte array containing bits in order from left to right 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * InvalidParameterException - if numBytes < 0 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected byte[] engineGenerateSeed(int numBytes) { 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] myBytes; // byte[] for bytes returned by "nextBytes()" 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (numBytes < 0) { 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NegativeArraySizeException(Messages.getString("security.171", numBytes)); //$NON-NLS-1$ 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (numBytes == 0) { 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return new byte[0]; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (myRandom == null) { 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project myRandom = new SHA1PRNG_SecureRandomImpl(); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project myRandom.engineSetSeed(RandomBitsSupplier 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .getRandomBits(DIGEST_LENGTH)); 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project myBytes = new byte[numBytes]; 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project myRandom.engineNextBytes(myBytes); 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return myBytes; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes random bytes into an array supplied. 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Bits in a byte are from left to right. <BR> 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * To generate random bytes, the "expansion of source bits" method is used, 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that is, 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the current seed with a 64-bit counter appended is used to compute new bits. 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The counter is incremented by 1 for each 20-byte output. <BR> 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The method overrides engineNextBytes in class SecureRandomSpi. 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * bytes - byte array to be filled in with bytes 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NullPointerException - if null is passed to the "bytes" argument 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void engineNextBytes(byte[] bytes) { 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, n; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long bits; // number of bits required by Secure Hash Standard 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextByteToReturn; // index of ready bytes in "bytes" array 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int lastWord; // index of last word in frame containing bytes 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final int extrabytes = 7;// # of bytes to add in order to computer # of 8 byte words 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytes == null) { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException( 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Messages.getString("security.83", "bytes")); //$NON-NLS-1$ //$NON-NLS-2$ 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastWord = seed[BYTES_OFFSET] == 0 ? 0 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project : (seed[BYTES_OFFSET] + extrabytes) >> 3 - 1; 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (state == UNDEFINED) { 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // no seed supplied by user, hence it is generated thus randomizing internal state 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateSeed(RandomBitsSupplier.getRandomBits(DIGEST_LENGTH)); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBIndex = HASHBYTES_TO_USE; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (state == SET_SEED) { 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(seed, HASH_OFFSET, copies, HASHCOPY_OFFSET, 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXTRAFRAME_OFFSET); 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // possible cases for 64-byte frame: 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // seed bytes < 48 - remaining bytes are enough for all, 8 counter bytes, 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 0x80, and 8 seedLength bytes; no extra frame required 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 48 < seed bytes < 56 - remaining 9 bytes are for 0x80 and 8 counter bytes 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // extra frame contains only seedLength value at the end 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // seed bytes > 55 - extra frame contains both counter's bytes 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // at the beginning and seedLength value at the end; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // note, that beginning extra bytes are not more than 8, 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // that is, only 2 extra words may be used 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // no need to set to "0" 3 words after "lastWord" and 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // more than two words behind frame 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = lastWord + 3; i < FRAME_LENGTH + 2; i++) { 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[i] = 0; 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bits = seedLength << 3 + 64; // transforming # of bytes into # of bits 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // putting # of bits into two last words (14,15) of 16 word frame in 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // seed or copies array depending on total length after padding 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (seed[BYTES_OFFSET] < MAX_BYTES) { 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[14] = (int) (bits >>> 32); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[15] = (int) (bits & 0xFFFFFFFF); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copies[EXTRAFRAME_OFFSET + 14] = (int) (bits >>> 32); 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copies[EXTRAFRAME_OFFSET + 15] = (int) (bits & 0xFFFFFFFF); 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBIndex = HASHBYTES_TO_USE; // skipping remaining random bits 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = NEXT_BYTES; 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bytes.length == 0) { 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextByteToReturn = 0; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // possibly not all of HASHBYTES_TO_USE bytes were used previous time 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project n = (HASHBYTES_TO_USE - nextBIndex) < (bytes.length - nextByteToReturn) ? HASHBYTES_TO_USE 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - nextBIndex 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project : bytes.length - nextByteToReturn; 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n > 0) { 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(nextBytes, nextBIndex, bytes, nextByteToReturn, n); 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBIndex += n; 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextByteToReturn += n; 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nextByteToReturn >= bytes.length) { 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; // return because "bytes[]" are filled in 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project n = seed[BYTES_OFFSET] & 0x03; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (;;) { 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n == 0) { 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[lastWord] = (int) (counter >>> 32); 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[lastWord + 1] = (int) (counter & 0xFFFFFFFF); 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[lastWord + 2] = END_FLAGS[0]; 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[lastWord] |= (int) ((counter >>> RIGHT1[n]) & MASK[n]); 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[lastWord + 1] = (int) ((counter >>> RIGHT2[n]) & 0xFFFFFFFF); 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[lastWord + 2] = (int) ((counter << LEFT[n]) | END_FLAGS[n]); 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (seed[BYTES_OFFSET] > MAX_BYTES) { 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copies[EXTRAFRAME_OFFSET] = seed[FRAME_LENGTH]; 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copies[EXTRAFRAME_OFFSET + 1] = seed[FRAME_LENGTH + 1]; 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SHA1Impl.computeHash(seed); 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (seed[BYTES_OFFSET] > MAX_BYTES) { 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(seed, 0, copies, FRAME_OFFSET, FRAME_LENGTH); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(copies, EXTRAFRAME_OFFSET, seed, 0, 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FRAME_LENGTH); 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SHA1Impl.computeHash(seed); 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(copies, FRAME_OFFSET, seed, 0, FRAME_LENGTH); 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project counter++; 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int j = 0; 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < EXTRAFRAME_OFFSET; i++) { 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int k = seed[HASH_OFFSET + i]; 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBytes[j] = (byte) (k >>> 24); // getting first byte from left 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBytes[j + 1] = (byte) (k >>> 16); // getting second byte from left 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBytes[j + 2] = (byte) (k >>> 8); // getting third byte from left 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBytes[j + 3] = (byte) (k); // getting fourth byte from left 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project j += 4; 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBIndex = 0; 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project j = HASHBYTES_TO_USE < (bytes.length - nextByteToReturn) ? HASHBYTES_TO_USE 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project : bytes.length - nextByteToReturn; 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (j > 0) { 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(nextBytes, 0, bytes, nextByteToReturn, j); 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextByteToReturn += j; 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBIndex += j; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nextByteToReturn >= bytes.length) { 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void writeObject(ObjectOutputStream oos) throws IOException { 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] intData = null; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final int only_hash = EXTRAFRAME_OFFSET; 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final int hashes_and_frame = EXTRAFRAME_OFFSET * 2 + FRAME_LENGTH; 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final int hashes_and_frame_extra = EXTRAFRAME_OFFSET * 2 + FRAME_LENGTH 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2; 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.writeLong(seedLength); 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.writeLong(counter); 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.writeInt(state); 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.writeInt(seed[BYTES_OFFSET]); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nRemaining = (seed[BYTES_OFFSET] + 3) >> 2; // converting bytes in words 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // result may be 0 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (state != NEXT_BYTES) { 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // either the state is UNDEFINED or previous method was "setSeed(..)" 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // so in "seed[]" to serialize are remaining bytes (seed[0-nRemaining]) and 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // current hash (seed[82-86]) 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intData = new int[only_hash + nRemaining]; 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(seed, 0, intData, 0, nRemaining); 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(seed, HASH_OFFSET, intData, nRemaining, 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXTRAFRAME_OFFSET); 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // previous method was "nextBytes(..)" 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // so, data to serialize are all the above (two first are in "copies" array) 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // and current words in both frame and extra frame (as if) 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int offset = 0; 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (seed[BYTES_OFFSET] < MAX_BYTES) { // no extra frame 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intData = new int[hashes_and_frame + nRemaining]; 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { // extra frame is used 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intData = new int[hashes_and_frame_extra + nRemaining]; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intData[offset] = seed[FRAME_LENGTH]; 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intData[offset + 1] = seed[FRAME_LENGTH + 1]; 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intData[offset + 2] = seed[FRAME_LENGTH + 14]; 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project intData[offset + 3] = seed[FRAME_LENGTH + 15]; 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += 4; 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(seed, 0, intData, offset, FRAME_LENGTH); 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += FRAME_LENGTH; 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(copies, FRAME_LENGTH + EXTRAFRAME_OFFSET, intData, 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset, nRemaining); 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += nRemaining; 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(copies, 0, intData, offset, EXTRAFRAME_OFFSET); 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset += EXTRAFRAME_OFFSET; 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(seed, HASH_OFFSET, intData, offset, 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXTRAFRAME_OFFSET); 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < intData.length; i++) { 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.writeInt(intData[i]); 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.writeInt(nextBIndex); 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project oos.write(nextBytes, nextBIndex, HASHBYTES_TO_USE - nextBIndex); 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void readObject(ObjectInputStream ois) throws IOException, 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassNotFoundException { 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed = new int[HASH_OFFSET + EXTRAFRAME_OFFSET]; 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copies = new int[2 * FRAME_LENGTH + EXTRAFRAME_OFFSET]; 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBytes = new byte[DIGEST_LENGTH]; 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seedLength = ois.readLong(); 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project counter = ois.readLong(); 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state = ois.readInt(); 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[BYTES_OFFSET] = ois.readInt(); 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nRemaining = (seed[BYTES_OFFSET] + 3) >> 2; // converting bytes in words 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (state != NEXT_BYTES) { 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < nRemaining; i++) { 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[i] = ois.readInt(); 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < EXTRAFRAME_OFFSET; i++) { 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[HASH_OFFSET + i] = ois.readInt(); 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (seed[BYTES_OFFSET] >= MAX_BYTES) { 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // reading next bytes in seed extra frame 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[FRAME_LENGTH] = ois.readInt(); 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[FRAME_LENGTH + 1] = ois.readInt(); 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[FRAME_LENGTH + 14] = ois.readInt(); 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[FRAME_LENGTH + 15] = ois.readInt(); 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // reading next bytes in seed frame 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < FRAME_LENGTH; i++) { 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[i] = ois.readInt(); 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // reading remaining seed bytes 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < nRemaining; i++) { 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copies[FRAME_LENGTH + EXTRAFRAME_OFFSET + i] = ois.readInt(); 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // reading copy of current hash 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < EXTRAFRAME_OFFSET; i++) { 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project copies[i] = ois.readInt(); 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // reading current hash 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < EXTRAFRAME_OFFSET; i++) { 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seed[HASH_OFFSET + i] = ois.readInt(); 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextBIndex = ois.readInt(); 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ois.read(nextBytes, nextBIndex, HASHBYTES_TO_USE - nextBIndex); 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 538