From 9ea9bd96bb9e9d5a7c68a42a7bbdb15c9fd2a192 Mon Sep 17 00:00:00 2001 From: dangfan Date: Wed, 21 Apr 2021 09:25:59 +0800 Subject: [PATCH] fix the compatibility of compressed and uncompressed format in ECDH --- .../operations/PsoDecryptTokenOp.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/PsoDecryptTokenOp.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/PsoDecryptTokenOp.java index 537c92b5a..649211493 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/PsoDecryptTokenOp.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/securitytoken/operations/PsoDecryptTokenOp.java @@ -161,14 +161,23 @@ public class PsoDecryptTokenOp { */ byte[] keyEncryptionKey = response.getData(); - int xLen; - if (eckf.isX25519()) { - xLen = keyEncryptionKey.length; - } else { + /* From rfc6637#section-7 : + The input of KDF should be the x portion of the point. + As the result of ECDH can be expressed in two formats: compressed and uncompressed, + we have to deal with each case. + */ + int xLen, startPos; + if (keyEncryptionKey[0] == 0x04 && keyEncryptionKey.length % 2 == 1) { + // uncompressed format xLen = (keyEncryptionKey.length - 1) / 2; + startPos = 1; + } else { + // compressed format + xLen = keyEncryptionKey.length; + startPos = 0; } final byte[] kekX = new byte[xLen]; - System.arraycopy(keyEncryptionKey, eckf.isX25519() ? 0 : 1, kekX, 0, xLen); + System.arraycopy(keyEncryptionKey, startPos, kekX, 0, xLen); final byte[] keyEnc = new byte[encryptedSessionKeyMpi[mpiLength + 2]];