383 random = JCAUtil.getSecureRandom(); 384 } 385 iv = new byte[blockSize]; 386 random.nextBytes(iv); 387 } else { 388 if (iv.length != blockSize) { 389 throw new InvalidAlgorithmParameterException 390 ("IV length must match block size"); 391 } 392 } 393 } 394 this.iv = iv; 395 p11Key = P11SecretKeyFactory.convertKey(token, key, keyAlgorithm); 396 try { 397 initialize(); 398 } catch (PKCS11Exception e) { 399 throw new InvalidKeyException("Could not initialize cipher", e); 400 } 401 } 402 403 private void cancelOperation() { 404 if (initialized == false) { 405 return; 406 } 407 408 if ((session == null) || (token.explicitCancel == false)) { 409 return; 410 } 411 try { 412 if (session.hasObjects() == false) { 413 session = token.killSession(session); 414 return; 415 } else { 416 // cancel operation by finishing it 417 int bufLen = doFinalLength(0); 418 byte[] buffer = new byte[bufLen]; 419 if (encrypt) { 420 token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen); 421 } else { 422 token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen); 423 } 424 } 425 } catch (PKCS11Exception e) { 426 throw new ProviderException("Cancel failed", e); 427 } 428 } 429 430 private void ensureInitialized() throws PKCS11Exception { 431 if (initialized == false) { 432 initialize(); 433 } 434 } 435 436 private void initialize() throws PKCS11Exception { 437 if (session == null) { 438 session = token.getOpSession(); 439 } 440 CK_MECHANISM mechParams = (blockMode == MODE_CTR? 441 new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) : 442 new CK_MECHANISM(mechanism, iv)); 443 444 try { 445 if (encrypt) { 446 token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID); 447 } else { 448 token.p11.C_DecryptInit(session.id(), mechParams, p11Key.keyID); 449 } 450 } catch (PKCS11Exception ex) { 451 // release session when initialization failed 452 session = token.releaseSession(session); 453 throw ex; 454 } 455 bytesBuffered = 0; 456 padBufferLen = 0; 457 initialized = true; 458 } 459 460 // if update(inLen) is called, how big does the output buffer have to be? 461 private int updateLength(int inLen) { 462 if (inLen <= 0) { 463 return 0; 464 } 465 466 int result = inLen + bytesBuffered; 467 if (blockSize != 0 && blockMode != MODE_CTR) { 468 // minus the number of bytes in the last incomplete block. 469 result -= (result & (blockSize - 1)); 470 } 471 return result; 472 } 473 474 // if doFinal(inLen) is called, how big does the output buffer have to be? 475 private int doFinalLength(int inLen) { 476 if (inLen < 0) { 477 return 0; 478 } 479 480 int result = inLen + bytesBuffered; 481 if (blockSize != 0 && encrypt && paddingType != PAD_NONE) { 482 // add the number of bytes to make the last block complete. 483 result += (blockSize - (result & (blockSize - 1))); 484 } 485 return result; 486 } 487 488 // reset the states to the pre-initialized values 489 private void reset(boolean doCancel) { 490 if (doCancel) cancelOperation(); 491 492 initialized = false; 493 bytesBuffered = 0; 494 padBufferLen = 0; 495 if (session != null) { 496 session = token.releaseSession(session); 497 } 498 } 499 500 // see JCE spec 501 protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) { 502 try { 503 byte[] out = new byte[updateLength(inLen)]; 504 int n = engineUpdate(in, inOfs, inLen, out, 0); 505 return P11Util.convert(out, 0, n); 506 } catch (ShortBufferException e) { 507 // convert since the output length is calculated by updateLength() 508 throw new ProviderException(e); 509 } 510 } 511 512 // see JCE spec 513 protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out, 514 int outOfs) throws ShortBufferException { 515 int outLen = out.length - outOfs; 516 return implUpdate(in, inOfs, inLen, out, outOfs, outLen); 517 } | 383 random = JCAUtil.getSecureRandom(); 384 } 385 iv = new byte[blockSize]; 386 random.nextBytes(iv); 387 } else { 388 if (iv.length != blockSize) { 389 throw new InvalidAlgorithmParameterException 390 ("IV length must match block size"); 391 } 392 } 393 } 394 this.iv = iv; 395 p11Key = P11SecretKeyFactory.convertKey(token, key, keyAlgorithm); 396 try { 397 initialize(); 398 } catch (PKCS11Exception e) { 399 throw new InvalidKeyException("Could not initialize cipher", e); 400 } 401 } 402 403 // reset the states to the pre-initialized values 404 private void reset(boolean doCancel) { 405 if (!initialized) { 406 return; 407 } 408 initialized = false; 409 try { 410 if (session == null) { 411 return; 412 } 413 if (doCancel && token.explicitCancel) { 414 cancelOperation(); 415 } 416 } finally { 417 p11Key.decNativeKeyRef(); 418 session = token.releaseSession(session); 419 bytesBuffered = 0; 420 padBufferLen = 0; 421 } 422 } 423 424 private void cancelOperation() { 425 token.ensureValid(); 426 if (session.hasObjects() == false) { 427 session = token.killSession(session); 428 return; 429 } else { 430 try { 431 // cancel operation by finishing it 432 int bufLen = doFinalLength(0); 433 byte[] buffer = new byte[bufLen]; 434 if (encrypt) { 435 token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen); 436 } else { 437 token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen); 438 } 439 } catch (PKCS11Exception e) { 440 throw new ProviderException("Cancel failed", e); 441 } 442 } 443 } 444 445 private void ensureInitialized() throws PKCS11Exception { 446 if (initialized == false) { 447 initialize(); 448 } 449 } 450 451 private void initialize() throws PKCS11Exception { 452 if (p11Key == null) { 453 initialized = false; 454 throw new ProviderException( 455 "Operation cannot be performed without" 456 + " calling engineInit first"); 457 } 458 token.ensureValid(); 459 p11Key.incNativeKeyRef(); 460 try { 461 if (session == null) { 462 session = token.getOpSession(); 463 } 464 CK_MECHANISM mechParams = (blockMode == MODE_CTR? 465 new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) : 466 new CK_MECHANISM(mechanism, iv)); 467 if (encrypt) { 468 token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID); 469 } else { 470 token.p11.C_DecryptInit(session.id(), mechParams, p11Key.keyID); 471 } 472 } catch (PKCS11Exception e) { 473 p11Key.decNativeKeyRef(); 474 session = token.releaseSession(session); 475 initialized = false; 476 throw e; 477 } 478 initialized = true; 479 bytesBuffered = 0; 480 padBufferLen = 0; 481 } 482 483 // if update(inLen) is called, how big does the output buffer have to be? 484 private int updateLength(int inLen) { 485 if (inLen <= 0) { 486 return 0; 487 } 488 489 int result = inLen + bytesBuffered; 490 if (blockSize != 0 && blockMode != MODE_CTR) { 491 // minus the number of bytes in the last incomplete block. 492 result -= (result & (blockSize - 1)); 493 } 494 return result; 495 } 496 497 // if doFinal(inLen) is called, how big does the output buffer have to be? 498 private int doFinalLength(int inLen) { 499 if (inLen < 0) { 500 return 0; 501 } 502 503 int result = inLen + bytesBuffered; 504 if (blockSize != 0 && encrypt && paddingType != PAD_NONE) { 505 // add the number of bytes to make the last block complete. 506 result += (blockSize - (result & (blockSize - 1))); 507 } 508 return result; 509 } 510 511 // see JCE spec 512 protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) { 513 try { 514 byte[] out = new byte[updateLength(inLen)]; 515 int n = engineUpdate(in, inOfs, inLen, out, 0); 516 return P11Util.convert(out, 0, n); 517 } catch (ShortBufferException e) { 518 // convert since the output length is calculated by updateLength() 519 throw new ProviderException(e); 520 } 521 } 522 523 // see JCE spec 524 protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out, 525 int outOfs) throws ShortBufferException { 526 int outLen = out.length - outOfs; 527 return implUpdate(in, inOfs, inLen, out, outOfs, outLen); 528 } |