1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.crypto.signers; 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.SecureRandom; 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.AsymmetricBlockCipher; 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.CipherParameters; 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.CryptoException; 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.Digest; 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.SignerWithRecovery; 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-removed 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// import org.bouncycastle.crypto.digests.RIPEMD128Digest; 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// import org.bouncycastle.crypto.digests.RIPEMD160Digest; 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-removed 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.digests.SHA1Digest; 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.ParametersWithRandom; 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.ParametersWithSalt; 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.crypto.params.RSAKeyParameters; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ISO9796-2 - mechanism using a hash function with recovery (scheme 2 and 3). 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note: the usual length for the salt is the length of the hash 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * function used in bytes. 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class ISO9796d2PSSSigner 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project implements SignerWithRecovery 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final public int TRAILER_IMPLICIT = 0xBC; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final public int TRAILER_RIPEMD160 = 0x31CC; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final public int TRAILER_RIPEMD128 = 0x32CC; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final public int TRAILER_SHA1 = 0x33CC; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Digest digest; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private AsymmetricBlockCipher cipher; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private SecureRandom random; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] standardSalt; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int hLen; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int trailer; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int keyBits; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] block; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] mBuf; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int messageLength; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int saltLength; 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean fullMessage; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] recoveredMessage; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate a signer for the with either implicit or explicit trailers 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for ISO9796-2, scheme 2 or 3. 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param cipher base cipher to use for signature creation/verification 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param digest digest to use. 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param saltLength length of salt in bytes. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param implicit whether or not the trailer is implicit or gives the hash. 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ISO9796d2PSSSigner( 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AsymmetricBlockCipher cipher, 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Digest digest, 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int saltLength, 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean implicit) 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.cipher = cipher; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.digest = digest; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.hLen = digest.getDigestSize(); 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.saltLength = saltLength; 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (implicit) 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project trailer = TRAILER_IMPLICIT; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (digest instanceof SHA1Digest) 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project trailer = TRAILER_SHA1; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-removed 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // else if (digest instanceof RIPEMD160Digest) 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // { 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // trailer = TRAILER_RIPEMD160; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // } 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // else if (digest instanceof RIPEMD128Digest) 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // { 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // trailer = TRAILER_RIPEMD128; 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // } 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-removed 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("no valid trailer for digest"); 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructor for a signer with an explicit digest trailer. 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param cipher cipher to use. 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param digest digest to sign with. 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param saltLength length of salt in bytes. 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ISO9796d2PSSSigner( 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project AsymmetricBlockCipher cipher, 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Digest digest, 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int saltLength) 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(cipher, digest, saltLength, false); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialise the signer. 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param forSigning true if for signing, false if for verification. 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param param parameters for signature generation/verification. If the 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * parameters are for generation they should be a ParametersWithRandom, 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a ParametersWithSalt, or just an RSAKeyParameters object. If RSAKeyParameters 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are passed in a SecureRandom will be created. 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @exception IllegalArgumentException if wrong parameter type or a fixed 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * salt is passed in which is the wrong length. 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void init( 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean forSigning, 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CipherParameters param) 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RSAKeyParameters kParam = null; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int lengthOfSalt = saltLength; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (param instanceof ParametersWithRandom) 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParametersWithRandom p = (ParametersWithRandom)param; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kParam = (RSAKeyParameters)p.getParameters(); 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project random = p.getRandom(); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else if (param instanceof ParametersWithSalt) 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ParametersWithSalt p = (ParametersWithSalt)param; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kParam = (RSAKeyParameters)p.getParameters(); 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project standardSalt = p.getSalt(); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lengthOfSalt = standardSalt.length; 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kParam = (RSAKeyParameters)param; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (forSigning) 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project random = new SecureRandom(); 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cipher.init(forSigning, kParam); 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project keyBits = kParam.getModulus().bitLength(); 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block = new byte[(keyBits + 7) / 8]; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (trailer == TRAILER_IMPLICIT) 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mBuf = new byte[block.length - digest.getDigestSize() - lengthOfSalt - 1 - 1]; 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mBuf = new byte[block.length - digest.getDigestSize() - lengthOfSalt - 1 - 2]; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reset(); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * compare two byte arrays. 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean isSameAs( 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] a, 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] b) 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (messageLength != b.length) 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i != b.length; i++) 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (a[i] != b[i]) 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * clear possible sensitive data 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void clearBlock( 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] block) 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i != block.length; i++) 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[i] = 0; 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * update the internal digest with the byte b 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void update( 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte b) 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (messageLength < mBuf.length) 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mBuf[messageLength++] = b; 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(b); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * update the internal digest with the byte array in 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void update( 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] in, 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int off, 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len) 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (len > 0 && messageLength < mBuf.length) 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.update(in[off]); 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project off++; 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len--; 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len > 0) 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(in, off, len); 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reset the internal state 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void reset() 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.reset(); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project messageLength = 0; 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (recoveredMessage != null) 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(recoveredMessage); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project recoveredMessage = null; 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fullMessage = false; 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * generate a signature for the loaded message using the key we were 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * initialised with. 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public byte[] generateSignature() 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws CryptoException 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int digSize = digest.getDigestSize(); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] m2Hash = new byte[digSize]; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.doFinal(m2Hash, 0); 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] C = new byte[8]; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LtoOSP(messageLength * 8, C); 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(C, 0, C.length); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(mBuf, 0, messageLength); 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(m2Hash, 0, m2Hash.length); 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] salt; 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (standardSalt != null) 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project salt = standardSalt; 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project salt = new byte[saltLength]; 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project random.nextBytes(salt); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(salt, 0, salt.length); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] hash = new byte[digest.getDigestSize()]; 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.doFinal(hash, 0); 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int tLength = 2; 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (trailer == TRAILER_IMPLICIT) 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tLength = 1; 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int off = block.length - messageLength - salt.length - hLen - tLength - 1; 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[off] = 0x01; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(mBuf, 0, block, off + 1, messageLength); 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(salt, 0, block, off + 1 + messageLength, salt.length); 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] dbMask = maskGeneratorFunction1(hash, 0, hash.length, block.length - hLen - tLength); 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i != dbMask.length; i++) 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[i] ^= dbMask[i]; 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(hash, 0, block, block.length - hLen - tLength, hLen); 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (trailer == TRAILER_IMPLICIT) 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[block.length - 1] = (byte)TRAILER_IMPLICIT; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[block.length - 2] = (byte)(trailer >>> 8); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[block.length - 1] = (byte)trailer; 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[0] &= 0x7f; 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] b = cipher.processBlock(block, 0, block.length); 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(mBuf); 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(block); 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project messageLength = 0; 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return b; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return true if the signature represents a ISO9796-2 signature 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for the passed in message. 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean verifySignature( 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] signature) 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] block = null; 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block = cipher.processBlock(signature, 0, signature.length); 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catch (Exception e) 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // adjust block size for leading zeroes if necessary 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (block.length < (keyBits + 7) / 8) 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] tmp = new byte[(keyBits + 7) / 8]; 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(block, 0, tmp, tmp.length - block.length, block.length); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block = tmp; 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int tLength = 0; 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tLength = 1; 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (sigTrail) 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-removed 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // case TRAILER_RIPEMD160: 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // if (!(digest instanceof RIPEMD160Digest)) 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // { 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // throw new IllegalStateException("signer should be initialised with RIPEMD160"); 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // } 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // break; 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-removed 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case TRAILER_SHA1: 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(digest instanceof SHA1Digest)) 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalStateException("signer should be initialised with SHA1"); 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BEGIN android-removed 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // case TRAILER_RIPEMD128: 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // if (!(digest instanceof RIPEMD128Digest)) 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // { 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // throw new IllegalStateException("signer should be initialised with RIPEMD128"); 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // } 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // break; 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // END android-removed 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("unrecognised hash in signature"); 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tLength = 2; 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // calculate H(m2) 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] m2Hash = new byte[hLen]; 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.doFinal(m2Hash, 0); 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // remove the mask 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] dbMask = maskGeneratorFunction1(block, block.length - hLen - tLength, hLen, block.length - hLen - tLength); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i != dbMask.length; i++) 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[i] ^= dbMask[i]; 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project block[0] &= 0x7f; 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // find out how much padding we've got 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mStart = 0; 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (mStart = 0; mStart != block.length; mStart++) 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (block[mStart] == 0x01) 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mStart++; 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mStart >= block.length) 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(block); 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mStart > 1) 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fullMessage = true; 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fullMessage = false; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project recoveredMessage = new byte[dbMask.length - mStart - saltLength]; 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // check the hashes 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] C = new byte[8]; 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LtoOSP(recoveredMessage.length * 8, C); 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(C, 0, C.length); 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (recoveredMessage.length != 0) 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(recoveredMessage, 0, recoveredMessage.length); 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(m2Hash, 0, m2Hash.length); 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] hash = new byte[digest.getDigestSize()]; 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(block, mStart + recoveredMessage.length, dbMask.length - mStart - recoveredMessage.length); 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.doFinal(hash, 0); 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int off = block.length - tLength - hash.length; 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i != hash.length; i++) 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (hash[i] != block[off + i]) 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(block); 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(hash); 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(recoveredMessage); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fullMessage = false; 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // if they've input a message check what we've recovered against 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // what was input. 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (messageLength != 0) 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isSameAs(mBuf, recoveredMessage)) 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(mBuf); 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(block); 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(mBuf); 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearBlock(block); 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project messageLength = 0; 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return true if the full message was recoveredMessage. 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return true on full message recovery, false otherwise, or if not sure. 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see org.bouncycastle.crypto.SignerWithRecovery#hasFullMessage() 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean hasFullMessage() 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return fullMessage; 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a reference to the recoveredMessage message. 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the full/partial recoveredMessage message. 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see org.bouncycastle.crypto.SignerWithRecovery#getRecoveredMessage() 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public byte[] getRecoveredMessage() 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return recoveredMessage; 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * int to octet string. 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void ItoOSP( 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] sp) 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[0] = (byte)(i >>> 24); 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[1] = (byte)(i >>> 16); 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[2] = (byte)(i >>> 8); 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[3] = (byte)(i >>> 0); 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * long to octet string. 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void LtoOSP( 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long l, 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] sp) 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[0] = (byte)(l >>> 56); 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[1] = (byte)(l >>> 48); 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[2] = (byte)(l >>> 40); 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[3] = (byte)(l >>> 32); 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[4] = (byte)(l >>> 24); 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[5] = (byte)(l >>> 16); 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[6] = (byte)(l >>> 8); 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sp[7] = (byte)(l >>> 0); 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mask generator function, as described in PKCS1v2. 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] maskGeneratorFunction1( 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] Z, 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int zOff, 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int zLen, 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length) 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] mask = new byte[length]; 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] hashBuf = new byte[hLen]; 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] C = new byte[4]; 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int counter = 0; 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.reset(); 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (counter < (length / hLen)) 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ItoOSP(counter, C); 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(Z, zOff, zLen); 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(C, 0, C.length); 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.doFinal(hashBuf, 0); 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(hashBuf, 0, mask, counter * hLen, hLen); 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project counter++; 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((counter * hLen) < length) 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ItoOSP(counter, C); 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(Z, zOff, zLen); 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.update(C, 0, C.length); 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project digest.doFinal(hashBuf, 0); 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(hashBuf, 0, mask, counter * hLen, mask.length - (counter * hLen)); 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return mask; 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 612