private int implUpdate(byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws ShortBufferException { if (outLen < updateLength(inLen)) { throw new ShortBufferException(); } try { ensureInitialized(); int k = 0; if (encrypt) { k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen, 0, out, outOfs, outLen); } else { int newPadBufferLen = 0; if (paddingObj != null) { if (padBufferLen != 0) { // NSS throws up when called with data not in multiple // of blocks. Try to work around this by holding the // extra data in padBuffer. if (padBufferLen != padBuffer.length) { int bufCapacity = padBuffer.length - padBufferLen; if (inLen > bufCapacity) { bufferInputBytes(in, inOfs, bufCapacity); inOfs += bufCapacity; inLen -= bufCapacity; } else { bufferInputBytes(in, inOfs, inLen); return 0; } } k = token.p11.C_DecryptUpdate( session.id(), 0, padBuffer, 0, padBufferLen, 0, out, outOfs, outLen); padBufferLen = 0; } newPadBufferLen = inLen & (blockSize - 1); if (newPadBufferLen == 0) { newPadBufferLen = padBuffer.length; } inLen -= newPadBufferLen; } if (inLen > 0) { k += token.p11.C_DecryptUpdate( session.id(), 0, in, inOfs, inLen, 0, out, (outOfs + k), (outLen - k)); } // update 'padBuffer' if using our own padding impl. if (paddingObj != null) { bufferInputBytes(in, inOfs + inLen, newPadBufferLen); } } bytesBuffered += (inLen - k); return k; } catch (PKCS11Exception e) { if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) { throw (ShortBufferException) (new ShortBufferException().initCause(e)); } reset(); throw new ProviderException("update() failed", e); } }
private int implDoFinal(byte[] out, int outOfs, int outLen) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { int requiredOutLen = doFinalLength(0); if (outLen < requiredOutLen) { throw new ShortBufferException(); } try { ensureInitialized(); int k = 0; if (encrypt) { if (paddingObj != null) { int actualPadLen = paddingObj.setPaddingBytes(padBuffer, requiredOutLen - bytesBuffered); k = token.p11.C_EncryptUpdate( session.id(), 0, padBuffer, 0, actualPadLen, 0, out, outOfs, outLen); } k += token.p11.C_EncryptFinal(session.id(), 0, out, (outOfs + k), (outLen - k)); } else { if (paddingObj != null) { if (padBufferLen != 0) { k = token.p11.C_DecryptUpdate( session.id(), 0, padBuffer, 0, padBufferLen, 0, padBuffer, 0, padBuffer.length); } k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k, padBuffer.length - k); int actualPadLen = paddingObj.unpad(padBuffer, k); k -= actualPadLen; System.arraycopy(padBuffer, 0, out, outOfs, k); } else { k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs, outLen); } } return k; } catch (PKCS11Exception e) { handleException(e); throw new ProviderException("doFinal() failed", e); } finally { reset(); } }
private void cancelOperation() { if (initialized == false) { return; } initialized = false; if ((session == null) || (token.explicitCancel == false)) { return; } // cancel operation by finishing it int bufLen = doFinalLength(0); byte[] buffer = new byte[bufLen]; try { if (encrypt) { token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen); } else { token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen); } } catch (PKCS11Exception e) { throw new ProviderException("Cancel failed", e); } finally { reset(); } }
private void initialize() throws PKCS11Exception { if (session == null) { session = token.getOpSession(); } CK_MECHANISM mechParams = (blockMode == MODE_CTR ? new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) : new CK_MECHANISM(mechanism, iv)); try { if (encrypt) { token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID); } else { token.p11.C_DecryptInit(session.id(), mechParams, p11Key.keyID); } } catch (PKCS11Exception ex) { // release session when initialization failed session = token.releaseSession(session); throw ex; } bytesBuffered = 0; padBufferLen = 0; initialized = true; }
private int implDoFinal(ByteBuffer outBuffer) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { int outLen = outBuffer.remaining(); int requiredOutLen = doFinalLength(0); if (outLen < requiredOutLen) { throw new ShortBufferException(); } try { ensureInitialized(); long outAddr = 0; byte[] outArray = null; int outOfs = 0; if (outBuffer instanceof DirectBuffer) { outAddr = ((DirectBuffer) outBuffer).address(); outOfs = outBuffer.position(); } else { if (outBuffer.hasArray()) { outArray = outBuffer.array(); outOfs = outBuffer.position() + outBuffer.arrayOffset(); } else { outArray = new byte[outLen]; } } int k = 0; if (encrypt) { if (paddingObj != null) { int actualPadLen = paddingObj.setPaddingBytes(padBuffer, requiredOutLen - bytesBuffered); k = token.p11.C_EncryptUpdate( session.id(), 0, padBuffer, 0, actualPadLen, outAddr, outArray, outOfs, outLen); } k += token.p11.C_EncryptFinal(session.id(), outAddr, outArray, (outOfs + k), (outLen - k)); } else { if (paddingObj != null) { if (padBufferLen != 0) { k = token.p11.C_DecryptUpdate( session.id(), 0, padBuffer, 0, padBufferLen, 0, padBuffer, 0, padBuffer.length); padBufferLen = 0; } k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k, padBuffer.length - k); int actualPadLen = paddingObj.unpad(padBuffer, k); k -= actualPadLen; outArray = padBuffer; outOfs = 0; } else { k = token.p11.C_DecryptFinal(session.id(), outAddr, outArray, outOfs, outLen); } } if ((!encrypt && paddingObj != null) || (!(outBuffer instanceof DirectBuffer) && !outBuffer.hasArray())) { outBuffer.put(outArray, outOfs, k); } else { outBuffer.position(outBuffer.position() + k); } return k; } catch (PKCS11Exception e) { handleException(e); throw new ProviderException("doFinal() failed", e); } finally { reset(); } }
private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer) throws ShortBufferException { int inLen = inBuffer.remaining(); if (inLen <= 0) { return 0; } int outLen = outBuffer.remaining(); if (outLen < updateLength(inLen)) { throw new ShortBufferException(); } int origPos = inBuffer.position(); try { ensureInitialized(); long inAddr = 0; int inOfs = 0; byte[] inArray = null; if (inBuffer instanceof DirectBuffer) { inAddr = ((DirectBuffer) inBuffer).address(); inOfs = origPos; } else if (inBuffer.hasArray()) { inArray = inBuffer.array(); inOfs = (origPos + inBuffer.arrayOffset()); } long outAddr = 0; int outOfs = 0; byte[] outArray = null; if (outBuffer instanceof DirectBuffer) { outAddr = ((DirectBuffer) outBuffer).address(); outOfs = outBuffer.position(); } else { if (outBuffer.hasArray()) { outArray = outBuffer.array(); outOfs = (outBuffer.position() + outBuffer.arrayOffset()); } else { outArray = new byte[outLen]; } } int k = 0; if (encrypt) { if (inAddr == 0 && inArray == null) { inArray = new byte[inLen]; inBuffer.get(inArray); } else { inBuffer.position(origPos + inLen); } k = token.p11.C_EncryptUpdate( session.id(), inAddr, inArray, inOfs, inLen, outAddr, outArray, outOfs, outLen); } else { int newPadBufferLen = 0; if (paddingObj != null) { if (padBufferLen != 0) { // NSS throws up when called with data not in multiple // of blocks. Try to work around this by holding the // extra data in padBuffer. if (padBufferLen != padBuffer.length) { int bufCapacity = padBuffer.length - padBufferLen; if (inLen > bufCapacity) { bufferInputBytes(inBuffer, bufCapacity); inOfs += bufCapacity; inLen -= bufCapacity; } else { bufferInputBytes(inBuffer, inLen); return 0; } } k = token.p11.C_DecryptUpdate( session.id(), 0, padBuffer, 0, padBufferLen, outAddr, outArray, outOfs, outLen); padBufferLen = 0; } newPadBufferLen = inLen & (blockSize - 1); if (newPadBufferLen == 0) { newPadBufferLen = padBuffer.length; } inLen -= newPadBufferLen; } if (inLen > 0) { if (inAddr == 0 && inArray == null) { inArray = new byte[inLen]; inBuffer.get(inArray); } else { inBuffer.position(inBuffer.position() + inLen); } k += token.p11.C_DecryptUpdate( session.id(), inAddr, inArray, inOfs, inLen, outAddr, outArray, (outOfs + k), (outLen - k)); } // update 'padBuffer' if using our own padding impl. if (paddingObj != null && newPadBufferLen != 0) { bufferInputBytes(inBuffer, newPadBufferLen); } } bytesBuffered += (inLen - k); if (!(outBuffer instanceof DirectBuffer) && !outBuffer.hasArray()) { outBuffer.put(outArray, outOfs, k); } else { outBuffer.position(outBuffer.position() + k); } return k; } catch (PKCS11Exception e) { // Reset input buffer to its original position for inBuffer.position(origPos); if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) { throw (ShortBufferException) (new ShortBufferException().initCause(e)); } reset(); throw new ProviderException("update() failed", e); } }