aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwconner <wconner@google.com>2023-07-27 08:04:14 -0700
committerCopybara-Service <copybara-worker@google.com>2023-07-27 08:05:20 -0700
commita9862a149a956d6290ba4620e7733aaaef787b4f (patch)
treeb8adbac028ec4e06f38e9d6d9a569f33d36d2e8b
parent5619d180beb60770a8d1de5372d503959471d885 (diff)
downloadtink-a9862a149a956d6290ba4620e7733aaaef787b4f.tar.gz
Ensure that generated HPKE private keys are encoded to the correct length.
Also, added utility methods for determining HPKE key lengths from KEM id. PiperOrigin-RevId: 551532702
-rw-r--r--java_src/src/main/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel2
-rw-r--r--java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManager.java9
-rw-r--r--java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkeUtil.java32
-rw-r--r--java_src/src/test/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel1
-rw-r--r--java_src/src/test/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManagerTest.java4
5 files changed, 46 insertions, 2 deletions
diff --git a/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel b/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel
index 136bfac4c..880a3c611 100644
--- a/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel
+++ b/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel
@@ -165,6 +165,7 @@ java_library(
"//src/main/java/com/google/crypto/tink:hybrid_decrypt",
"//src/main/java/com/google/crypto/tink:key_template",
"//src/main/java/com/google/crypto/tink:registry",
+ "//src/main/java/com/google/crypto/tink/internal:big_integer_encoding",
"//src/main/java/com/google/crypto/tink/internal:key_type_manager",
"//src/main/java/com/google/crypto/tink/internal:primitive_factory",
"//src/main/java/com/google/crypto/tink/internal:private_key_type_manager",
@@ -417,6 +418,7 @@ android_library(
"//src/main/java/com/google/crypto/tink:hybrid_decrypt-android",
"//src/main/java/com/google/crypto/tink:key_template-android",
"//src/main/java/com/google/crypto/tink:registry-android",
+ "//src/main/java/com/google/crypto/tink/internal:big_integer_encoding-android",
"//src/main/java/com/google/crypto/tink/internal:key_type_manager-android",
"//src/main/java/com/google/crypto/tink/internal:primitive_factory-android",
"//src/main/java/com/google/crypto/tink/internal:private_key_type_manager-android",
diff --git a/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManager.java b/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManager.java
index 77cb832ef..60aae5677 100644
--- a/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManager.java
+++ b/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManager.java
@@ -19,6 +19,7 @@ package com.google.crypto.tink.hybrid.internal;
import com.google.crypto.tink.HybridDecrypt;
import com.google.crypto.tink.KeyTemplate;
import com.google.crypto.tink.Registry;
+import com.google.crypto.tink.internal.BigIntegerEncoding;
import com.google.crypto.tink.internal.KeyTypeManager;
import com.google.crypto.tink.internal.PrimitiveFactory;
import com.google.crypto.tink.internal.PrivateKeyTypeManager;
@@ -128,7 +129,8 @@ public final class HpkePrivateKeyManager
byte[] privateKeyBytes;
byte[] publicKeyBytes;
- switch (keyFormat.getParams().getKem()) {
+ HpkeKem kem = keyFormat.getParams().getKem();
+ switch (kem) {
case DHKEM_X25519_HKDF_SHA256:
privateKeyBytes = X25519.generatePrivateKey();
publicKeyBytes = X25519.publicFromPrivate(privateKeyBytes);
@@ -144,7 +146,10 @@ public final class HpkePrivateKeyManager
curveType,
EllipticCurves.PointFormatType.UNCOMPRESSED,
((ECPublicKey) keyPair.getPublic()).getW());
- privateKeyBytes = ((ECPrivateKey) keyPair.getPrivate()).getS().toByteArray();
+ privateKeyBytes =
+ BigIntegerEncoding.toBigEndianBytesOfFixedLength(
+ ((ECPrivateKey) keyPair.getPrivate()).getS(),
+ HpkeUtil.getEncodedPrivateKeyLength(kem));
break;
default:
throw new GeneralSecurityException("Invalid KEM");
diff --git a/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkeUtil.java b/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkeUtil.java
index 7639422c5..a71992409 100644
--- a/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkeUtil.java
+++ b/java_src/src/main/java/com/google/crypto/tink/hybrid/internal/HpkeUtil.java
@@ -143,5 +143,37 @@ public final class HpkeUtil {
}
}
+ /** Lengths from 'Npk' column in https://www.rfc-editor.org/rfc/rfc9180.html#table-2. */
+ static int getEncodedPublicKeyLength(HpkeKem kem) throws GeneralSecurityException {
+ switch (kem) {
+ case DHKEM_X25519_HKDF_SHA256:
+ return 32;
+ case DHKEM_P256_HKDF_SHA256:
+ return 65;
+ case DHKEM_P384_HKDF_SHA384:
+ return 97;
+ case DHKEM_P521_HKDF_SHA512:
+ return 133;
+ default:
+ throw new GeneralSecurityException("Unrecognized HPKE KEM identifier");
+ }
+ }
+
+ /** Lengths from 'Nsk' column in https://www.rfc-editor.org/rfc/rfc9180.html#table-2. */
+ static int getEncodedPrivateKeyLength(HpkeKem kem) throws GeneralSecurityException {
+ switch (kem) {
+ case DHKEM_X25519_HKDF_SHA256:
+ return 32;
+ case DHKEM_P256_HKDF_SHA256:
+ return 32;
+ case DHKEM_P384_HKDF_SHA384:
+ return 48;
+ case DHKEM_P521_HKDF_SHA512:
+ return 66;
+ default:
+ throw new GeneralSecurityException("Unrecognized HPKE KEM identifier");
+ }
+ }
+
private HpkeUtil() {}
}
diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel b/java_src/src/test/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel
index 5ca1e21d1..a3397c31a 100644
--- a/java_src/src/test/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel
+++ b/java_src/src/test/java/com/google/crypto/tink/hybrid/internal/BUILD.bazel
@@ -152,6 +152,7 @@ java_test(
"//src/main/java/com/google/crypto/tink/hybrid:hybrid_encrypt_wrapper",
"//src/main/java/com/google/crypto/tink/hybrid/internal:hpke_encrypt",
"//src/main/java/com/google/crypto/tink/hybrid/internal:hpke_private_key_manager",
+ "//src/main/java/com/google/crypto/tink/hybrid/internal:hpke_util",
"//src/main/java/com/google/crypto/tink/internal:key_type_manager",
"//src/main/java/com/google/crypto/tink/subtle:random",
"//src/main/java/com/google/crypto/tink/testing:test_util",
diff --git a/java_src/src/test/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManagerTest.java b/java_src/src/test/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManagerTest.java
index e92bb5d24..34f11ccfc 100644
--- a/java_src/src/test/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManagerTest.java
+++ b/java_src/src/test/java/com/google/crypto/tink/hybrid/internal/HpkePrivateKeyManagerTest.java
@@ -152,7 +152,11 @@ public final class HpkePrivateKeyManagerTest {
assertThat(key.getVersion()).isEqualTo(manager.getVersion());
assertThat(key.getPublicKey().getParams()).isEqualTo(format.getParams());
assertThat(key.getPublicKey().getPublicKey()).isNotEmpty();
+ assertThat(key.getPublicKey().getPublicKey().toByteArray().length)
+ .isEqualTo(HpkeUtil.getEncodedPublicKeyLength(format.getParams().getKem()));
assertThat(key.getPrivateKey()).isNotEmpty();
+ assertThat(key.getPrivateKey().toByteArray().length)
+ .isEqualTo(HpkeUtil.getEncodedPrivateKeyLength(format.getParams().getKem()));
}
@Theory