use of org.gudy.bouncycastle.crypto.DataLengthException in project BiglyBT by BiglySoftware.
the class RSAEngine method processBlock.
/**
* Process a single block using the basic RSA algorithm.
*
* @param in the input array.
* @param inOff the offset into the input buffer where the data starts.
* @param inLen the length of the data to be processed.
* @return the result of the RSA process.
* @exception DataLengthException the input block is too large.
*/
@Override
public byte[] processBlock(byte[] in, int inOff, int inLen) {
if (inLen > (getInputBlockSize() + 1)) {
throw new DataLengthException("input too large for RSA cipher.\n");
} else if (inLen == (getInputBlockSize() + 1) && (in[inOff] & 0x80) != 0) {
throw new DataLengthException("input too large for RSA cipher.\n");
}
byte[] block;
if (inOff != 0 || inLen != in.length) {
block = new byte[inLen];
System.arraycopy(in, inOff, block, 0, inLen);
} else {
block = in;
}
BigInteger input = new BigInteger(1, block);
byte[] output;
if (key instanceof RSAPrivateCrtKeyParameters) {
//
// we have the extra factors, use the Chinese Remainder Theorem - the author
// wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for
// advice regarding the expression of this.
//
RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters) key;
BigInteger p = crtKey.getP();
BigInteger q = crtKey.getQ();
BigInteger dP = crtKey.getDP();
BigInteger dQ = crtKey.getDQ();
BigInteger qInv = crtKey.getQInv();
BigInteger mP, mQ, h, m;
// mP = ((input mod p) ^ dP)) mod p
mP = (input.remainder(p)).modPow(dP, p);
// mQ = ((input mod q) ^ dQ)) mod q
mQ = (input.remainder(q)).modPow(dQ, q);
// h = qInv * (mP - mQ) mod p
h = mP.subtract(mQ);
h = h.multiply(qInv);
// mod (in Java) returns the positive residual
h = h.mod(p);
// m = h * q + mQ
m = h.multiply(q);
m = m.add(mQ);
output = m.toByteArray();
} else {
output = input.modPow(key.getExponent(), key.getModulus()).toByteArray();
}
if (forEncryption) {
if (// have ended up with an extra zero byte, copy down.
output[0] == 0 && output.length > getOutputBlockSize()) {
byte[] tmp = new byte[output.length - 1];
System.arraycopy(output, 1, tmp, 0, tmp.length);
return tmp;
}
if (// have ended up with less bytes than normal, lengthen
output.length < getOutputBlockSize()) {
byte[] tmp = new byte[getOutputBlockSize()];
System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length);
return tmp;
}
} else {
if (// have ended up with an extra zero byte, copy down.
output[0] == 0) {
byte[] tmp = new byte[output.length - 1];
System.arraycopy(output, 1, tmp, 0, tmp.length);
return tmp;
}
}
return output;
}
use of org.gudy.bouncycastle.crypto.DataLengthException in project BiglyBT by BiglySoftware.
the class CTSBlockCipher method doFinal.
/**
* Process the last block in the buffer.
*
* @param out the array the block currently being held is copied into.
* @param outOff the offset at which the copying starts.
* @return the number of output bytes copied to out.
* @exception DataLengthException if there is insufficient space in out for
* the output.
* @exception IllegalStateException if the underlying cipher is not
* initialised.
* @exception InvalidCipherTextException if cipher text decrypts wrongly (in
* case the exception will never get thrown).
*/
@Override
public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException, InvalidCipherTextException {
if (bufOff + outOff > out.length) {
throw new DataLengthException("output buffer to small in doFinal");
}
int blockSize = cipher.getBlockSize();
int len = bufOff - blockSize;
byte[] block = new byte[blockSize];
if (forEncryption) {
cipher.processBlock(buf, 0, block, 0);
for (int i = bufOff; i != buf.length; i++) {
buf[i] = block[i - blockSize];
}
for (int i = blockSize; i != bufOff; i++) {
buf[i] ^= block[i - blockSize];
}
if (cipher instanceof CBCBlockCipher) {
BlockCipher c = ((CBCBlockCipher) cipher).getUnderlyingCipher();
c.processBlock(buf, blockSize, out, outOff);
} else {
cipher.processBlock(buf, blockSize, out, outOff);
}
System.arraycopy(block, 0, out, outOff + blockSize, len);
} else {
byte[] lastBlock = new byte[blockSize];
if (cipher instanceof CBCBlockCipher) {
BlockCipher c = ((CBCBlockCipher) cipher).getUnderlyingCipher();
c.processBlock(buf, 0, block, 0);
} else {
cipher.processBlock(buf, 0, block, 0);
}
for (int i = blockSize; i != bufOff; i++) {
lastBlock[i - blockSize] = (byte) (block[i - blockSize] ^ buf[i]);
}
System.arraycopy(buf, blockSize, block, 0, len);
cipher.processBlock(block, 0, out, outOff);
System.arraycopy(lastBlock, 0, out, outOff + blockSize, len);
}
int offset = bufOff;
reset();
return offset;
}
Aggregations