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