136 lines
5.7 KiB
Diff
136 lines
5.7 KiB
Diff
From f4b0357c01f51e813642c3ac5c8ff33c1576eb72 Mon Sep 17 00:00:00 2001
|
|
Subject: Extending the IV Length Supported by KAEProvider AES/Gcm
|
|
---
|
|
.../security/openssl/kae_symmetric_cipher.c | 23 ++++++--
|
|
.../security/openssl/KAEGcmIvLenTest.java | 52 +++++++++++++++++++
|
|
2 files changed, 72 insertions(+), 3 deletions(-)
|
|
create mode 100644 jdk/test/org/openeuler/security/openssl/KAEGcmIvLenTest.java
|
|
|
|
diff --git a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c
|
|
index ec8894f1a..7618d6e16 100644
|
|
--- a/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c
|
|
+++ b/jdk/src/solaris/native/org/openeuler/security/openssl/kae_symmetric_cipher.c
|
|
@@ -146,6 +146,7 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
|
|
const EVP_CIPHER* cipher = NULL;
|
|
ENGINE* kaeEngine = NULL;
|
|
int keyLength = (*env)->GetArrayLength(env, key);
|
|
+ int ivLength = 0;
|
|
|
|
const char* algo = (*env)->GetStringUTFChars(env, cipherType, 0);
|
|
if (StartsWith("aes", algo)) {
|
|
@@ -158,7 +159,6 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
|
|
|
|
KAE_TRACE("KAESymmetricCipherBase_nativeInit: kaeEngine => %p", kaeEngine);
|
|
|
|
- (*env)->ReleaseStringUTFChars(env, cipherType, algo);
|
|
if (cipher == NULL) {
|
|
KAE_ThrowOOMException(env, "create EVP_CIPHER fail");
|
|
goto cleanup;
|
|
@@ -170,19 +170,35 @@ Java_org_openeuler_security_openssl_KAESymmetricCipherBase_nativeInit(JNIEnv* en
|
|
|
|
if (iv != NULL) {
|
|
ivBytes = (*env)->GetByteArrayElements(env, iv, NULL);
|
|
+ ivLength = (*env)->GetArrayLength(env, iv);
|
|
}
|
|
if (key != NULL) {
|
|
keyBytes = (*env)->GetByteArrayElements(env, key, NULL);
|
|
}
|
|
|
|
- if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, (const unsigned char*)keyBytes,
|
|
- (const unsigned char*)ivBytes, encrypt ? 1 : 0)) {
|
|
+ if (!EVP_CipherInit_ex(ctx, cipher, kaeEngine, NULL,
|
|
+ NULL, encrypt ? 1 : 0)) {
|
|
KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex failed", KAE_ThrowRuntimeException);
|
|
goto cleanup;
|
|
}
|
|
|
|
+ if (strcasecmp(algo + 8, "gcm") == 0) {
|
|
+ /* Set IV length if default 12 bytes (96 bits) is not appropriate */
|
|
+ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivLength, NULL)) {
|
|
+ KAE_ThrowFromOpenssl(env, "EVP_CIPHER_CTX_ctrl failed", KAE_ThrowRuntimeException);
|
|
+ goto cleanup;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!EVP_CipherInit_ex(ctx, NULL, kaeEngine, (const unsigned char*)keyBytes,
|
|
+ (const unsigned char*)ivBytes, encrypt ? 1 : 0)) {
|
|
+ KAE_ThrowFromOpenssl(env, "EVP_CipherInit_ex int key & iv failed", KAE_ThrowRuntimeException);
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
EVP_CIPHER_CTX_set_padding(ctx, padding ? 1 : 0);
|
|
|
|
+ (*env)->ReleaseStringUTFChars(env, cipherType, algo);
|
|
FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength);
|
|
return (jlong)ctx;
|
|
|
|
@@ -190,6 +206,7 @@ cleanup:
|
|
if (ctx != NULL) {
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
}
|
|
+ (*env)->ReleaseStringUTFChars(env, cipherType, algo);
|
|
FreeMemoryFromInit(env, iv, ivBytes, key, keyBytes, keyLength);
|
|
return 0;
|
|
}
|
|
diff --git a/jdk/test/org/openeuler/security/openssl/KAEGcmIvLenTest.java b/jdk/test/org/openeuler/security/openssl/KAEGcmIvLenTest.java
|
|
new file mode 100644
|
|
index 000000000..c9e2257aa
|
|
--- /dev/null
|
|
+++ b/jdk/test/org/openeuler/security/openssl/KAEGcmIvLenTest.java
|
|
@@ -0,0 +1,52 @@
|
|
+import org.openeuler.security.openssl.KAEProvider;
|
|
+
|
|
+import javax.crypto.Cipher;
|
|
+import javax.crypto.spec.GCMParameterSpec;
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
+import java.nio.charset.StandardCharsets;
|
|
+import java.security.Security;
|
|
+import java.util.Arrays;
|
|
+
|
|
+/**
|
|
+ * @test
|
|
+ * @summary Basic test for AES/GCM Iv
|
|
+ * @requires os.arch=="aarch64"
|
|
+ * @run main KAEGcmIvLenTest
|
|
+ */
|
|
+public class KAEGcmIvLenTest {
|
|
+ private static String plainText = "helloworldhellow"; // 16bytes for NoPadding
|
|
+ private static String shortPlainText = "helloworld"; // 5 bytes for padding
|
|
+ private static SecretKeySpec ks = new SecretKeySpec("AESEncryptionKey".getBytes(StandardCharsets.UTF_8), "AES"); // key has 16 bytes
|
|
+ private static int[] ivLens = {12, 16};
|
|
+ public static void main(String[] args) throws Exception {
|
|
+ Security.addProvider(new KAEProvider());
|
|
+ for (int ivLen : ivLens) {
|
|
+ testGcm(plainText,"AES/GCM/NoPadding", "KAEProvider", "SunJCE", ivLen);
|
|
+ testGcm(plainText,"AES/GCM/NoPadding", "SunJCE", "KAEProvider", ivLen);
|
|
+ testGcm(shortPlainText,"AES/GCM/PKCS5Padding", "KAEProvider", "SunJCE", ivLen);
|
|
+ testGcm(shortPlainText,"AES/GCM/PKCS5Padding", "SunJCE", "KAEProvider", ivLen);
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ private static void testGcm(String plainText, String algo, String encryptProvider, String decryptProvider, int ivLen) throws Exception {
|
|
+ Cipher enCipher = Cipher.getInstance(algo, encryptProvider);
|
|
+ enCipher.init(Cipher.ENCRYPT_MODE, ks, getIv(ivLen));
|
|
+ byte[] cipherText = enCipher.doFinal(plainText.getBytes());
|
|
+
|
|
+ Cipher deCipher = Cipher.getInstance(algo, decryptProvider);
|
|
+ deCipher.init(Cipher.DECRYPT_MODE, ks, getIv(ivLen));
|
|
+ byte[] origin = deCipher.doFinal(cipherText);
|
|
+
|
|
+ if (!Arrays.equals(plainText.getBytes(), origin)) {
|
|
+ throw new RuntimeException("gcm decryption failed, algo = " + algo);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static GCMParameterSpec getIv(int ivLen) {
|
|
+ if (ivLen == 16) {
|
|
+ return new GCMParameterSpec(128, "abcdefghabcdefgh".getBytes(StandardCharsets.UTF_8));
|
|
+ }
|
|
+ return new GCMParameterSpec(96, "abcdefghabcd".getBytes(StandardCharsets.UTF_8));
|
|
+ }
|
|
+}
|
|
--
|
|
2.19.1
|
|
|