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