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