提交 e4d49313 编写于 作者: V valeriep

6591117: Poor preformance of PKCS#11 security provider compared to Sun default provider

Summary: Added internal buffering to PKCS11 SecureRandom impl
Reviewed-by: wetmore
上级 38443947
/* /*
* Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
package sun.security.pkcs11; package sun.security.pkcs11;
import java.util.*; import java.util.*;
import java.io.*;
import java.security.*; import java.security.*;
import sun.security.pkcs11.wrapper.*; import sun.security.pkcs11.wrapper.*;
...@@ -61,9 +61,28 @@ final class P11SecureRandom extends SecureRandomSpi { ...@@ -61,9 +61,28 @@ final class P11SecureRandom extends SecureRandomSpi {
// buffer, if mixing is used // buffer, if mixing is used
private byte[] mixBuffer; private byte[] mixBuffer;
// bytes remaining in buffer, if mixing is used // bytes remaining in mixBuffer, if mixing is used
private int buffered; private int buffered;
/*
* we buffer data internally for efficiency but limit the lifetime
* to avoid using stale bits.
*/
// lifetime in ms, currently 100 ms (0.1 s)
private static final long MAX_IBUFFER_TIME = 100;
// size of the internal buffer
private static final int IBUFFER_SIZE = 32;
// internal buffer for the random bits
private transient byte[] iBuffer = new byte[IBUFFER_SIZE];
// number of bytes remain in iBuffer
private transient int ibuffered = 0;
// time that data was read into iBuffer
private transient long lastRead = 0L;
P11SecureRandom(Token token) { P11SecureRandom(Token token) {
this.token = token; this.token = token;
} }
...@@ -104,16 +123,29 @@ final class P11SecureRandom extends SecureRandomSpi { ...@@ -104,16 +123,29 @@ final class P11SecureRandom extends SecureRandomSpi {
if ((bytes == null) || (bytes.length == 0)) { if ((bytes == null) || (bytes.length == 0)) {
return; return;
} }
Session session = null; if (bytes.length <= IBUFFER_SIZE) {
try { int ofs = 0;
session = token.getOpSession(); synchronized (iBuffer) {
token.p11.C_GenerateRandom(session.id(), bytes); while (ofs < bytes.length) {
mix(bytes); long time = System.currentTimeMillis();
} catch (PKCS11Exception e) { // refill the internal buffer if empty or stale
throw new ProviderException("nextBytes() failed", e); if ((ibuffered == 0) ||
} finally { !(time - lastRead < MAX_IBUFFER_TIME)) {
token.releaseSession(session); lastRead = time;
implNextBytes(iBuffer);
ibuffered = IBUFFER_SIZE;
}
// copy the buffered bytes into 'bytes'
while ((ofs < bytes.length) && (ibuffered > 0)) {
bytes[ofs++] = iBuffer[IBUFFER_SIZE - ibuffered--];
}
}
}
} else {
// avoid using the buffer - just fill bytes directly
implNextBytes(bytes);
} }
} }
// see JCA spec // see JCA spec
...@@ -143,4 +175,17 @@ final class P11SecureRandom extends SecureRandomSpi { ...@@ -143,4 +175,17 @@ final class P11SecureRandom extends SecureRandomSpi {
} }
} }
// fill up the specified buffer with random bytes, and mix them
private void implNextBytes(byte[] bytes) {
Session session = null;
try {
session = token.getOpSession();
token.p11.C_GenerateRandom(session.id(), bytes);
mix(bytes);
} catch (PKCS11Exception e) {
throw new ProviderException("nextBytes() failed", e);
} finally {
token.releaseSession(session);
}
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册