1c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrompackage org.bouncycastle.crypto.engines; 2c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 35db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Rootimport java.math.BigInteger; 45db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Rootimport java.security.SecureRandom; 55db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root 6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.AsymmetricBlockCipher; 7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.CipherParameters; 8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.DataLengthException; 9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.params.ParametersWithRandom; 10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.params.RSAKeyParameters; 11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; 12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.util.BigIntegers; 13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom/** 15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * this does your basic RSA algorithm with blinding 16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 17c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrompublic class RSABlindedEngine 18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom implements AsymmetricBlockCipher 19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom{ 205db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root private static final BigInteger ONE = BigInteger.valueOf(1); 21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private RSACoreEngine core = new RSACoreEngine(); 23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private RSAKeyParameters key; 24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private SecureRandom random; 25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * initialise the RSA engine. 28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param forEncryption true if we are encrypting, false otherwise. 30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param param the necessary RSA key parameters. 31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 32c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public void init( 33c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean forEncryption, 34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom CipherParameters param) 35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom core.init(forEncryption, param); 37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (param instanceof ParametersWithRandom) 39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom ParametersWithRandom rParam = (ParametersWithRandom)param; 41c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom key = (RSAKeyParameters)rParam.getParameters(); 43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom random = rParam.getRandom(); 44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 46c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 47c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom key = (RSAKeyParameters)param; 48c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom random = new SecureRandom(); 49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * Return the maximum size for an input block to this engine. 54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * For RSA this is always one byte less than the key size on 55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * encryption, and the same length as the key size on decryption. 56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @return maximum size for an input block. 58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public int getInputBlockSize() 60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return core.getInputBlockSize(); 62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * Return the maximum size for an output block to this engine. 66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * For RSA this is always one byte less than the key size on 67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * decryption, and the same length as the key size on encryption. 68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @return maximum size for an output block. 70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public int getOutputBlockSize() 72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return core.getOutputBlockSize(); 74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * Process a single block using the basic RSA algorithm. 78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param in the input array. 80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param inOff the offset into the input buffer where the data starts. 81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param inLen the length of the data to be processed. 82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @return the result of the RSA process. 83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @exception DataLengthException the input block is too large. 84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public byte[] processBlock( 86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] in, 87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int inOff, 88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int inLen) 89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (key == null) 91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IllegalStateException("RSA engine not initialised"); 93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger input = core.convertInput(in, inOff, inLen); 96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger result; 98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (key instanceof RSAPrivateCrtKeyParameters) 99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom RSAPrivateCrtKeyParameters k = (RSAPrivateCrtKeyParameters)key; 101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger e = k.getPublicExponent(); 103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (e != null) // can't do blinding without a public exponent 104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger m = k.getModulus(); 106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger r = BigIntegers.createRandomInRange(ONE, m.subtract(ONE), random); 107c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 108c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger blindedInput = r.modPow(e, m).multiply(input).mod(m); 109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger blindedResult = core.processBlock(blindedInput); 110c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 111c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom BigInteger rInv = r.modInverse(m); 112c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom result = blindedResult.multiply(rInv).mod(m); 113c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 114c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 115c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 116c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom result = core.processBlock(input); 117c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 118c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 119c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom else 120c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 121c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom result = core.processBlock(input); 122c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 123c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 124c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return core.convertOutput(result); 125c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 126c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom} 127