Ed25519: use implementation from Tink
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
6789c11a7b
commit
53adb0e9a6
@ -11,7 +11,6 @@ buildscript {
|
|||||||
coreKtxVersion = '1.3.1'
|
coreKtxVersion = '1.3.1'
|
||||||
coroutinesVersion = '1.3.9'
|
coroutinesVersion = '1.3.9'
|
||||||
desugarVersion = '1.0.10'
|
desugarVersion = '1.0.10'
|
||||||
eddsaVersion = '0.3.0'
|
|
||||||
fragmentVersion = '1.2.5'
|
fragmentVersion = '1.2.5'
|
||||||
jsr305Version = '3.0.2'
|
jsr305Version = '3.0.2'
|
||||||
junitVersion = '4.13'
|
junitVersion = '4.13'
|
||||||
|
@ -53,7 +53,6 @@ dependencies {
|
|||||||
implementation "androidx.annotation:annotation:$annotationsVersion"
|
implementation "androidx.annotation:annotation:$annotationsVersion"
|
||||||
implementation "androidx.collection:collection:$collectionVersion"
|
implementation "androidx.collection:collection:$collectionVersion"
|
||||||
implementation "com.google.code.findbugs:jsr305:$jsr305Version"
|
implementation "com.google.code.findbugs:jsr305:$jsr305Version"
|
||||||
implementation "net.i2p.crypto:eddsa:$eddsaVersion"
|
|
||||||
testImplementation "junit:junit:$junitVersion"
|
testImplementation "junit:junit:$junitVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,14 +10,9 @@ import android.system.OsConstants;
|
|||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
|
|
||||||
import com.wireguard.android.util.RootShell.RootShellException;
|
import com.wireguard.android.util.RootShell.RootShellException;
|
||||||
|
import com.wireguard.crypto.Ed25519;
|
||||||
import com.wireguard.util.NonNullForAll;
|
import com.wireguard.util.NonNullForAll;
|
||||||
|
|
||||||
import net.i2p.crypto.eddsa.EdDSAEngine;
|
|
||||||
import net.i2p.crypto.eddsa.EdDSAPublicKey;
|
|
||||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
|
||||||
import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
|
|
||||||
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -28,7 +23,6 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.Signature;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -129,7 +123,7 @@ public class ModuleLoader {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Map<String, Sha256Digest> verifySignedHashes(final String signifyDigest) {
|
private Map<String, Sha256Digest> verifySignedHashes(final String signifyDigest) {
|
||||||
final byte[] publicKeyBytes = Base64.decode(MODULE_PUBLIC_KEY_BASE64, Base64.DEFAULT);
|
byte[] publicKeyBytes = Base64.decode(MODULE_PUBLIC_KEY_BASE64, Base64.DEFAULT);
|
||||||
|
|
||||||
if (publicKeyBytes == null || publicKeyBytes.length != 32 + 10 || publicKeyBytes[0] != 'E' || publicKeyBytes[1] != 'd')
|
if (publicKeyBytes == null || publicKeyBytes.length != 32 + 10 || publicKeyBytes[0] != 'E' || publicKeyBytes[1] != 'd')
|
||||||
return null;
|
return null;
|
||||||
@ -140,26 +134,17 @@ public class ModuleLoader {
|
|||||||
if (!lines[0].startsWith("untrusted comment: "))
|
if (!lines[0].startsWith("untrusted comment: "))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
final byte[] signatureBytes = Base64.decode(lines[1], Base64.DEFAULT);
|
byte[] signatureBytes = Base64.decode(lines[1], Base64.DEFAULT);
|
||||||
if (signatureBytes == null || signatureBytes.length != 64 + 10)
|
if (signatureBytes == null || signatureBytes.length != 64 + 10)
|
||||||
return null;
|
return null;
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
if (signatureBytes[i] != publicKeyBytes[i])
|
if (signatureBytes[i] != publicKeyBytes[i])
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
publicKeyBytes = Arrays.copyOfRange(publicKeyBytes, 10, 10 + 32);
|
||||||
try {
|
signatureBytes = Arrays.copyOfRange(signatureBytes, 10, 10 + 64);
|
||||||
final EdDSAParameterSpec parameterSpec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
|
if (!Ed25519.verify(lines[2].getBytes(StandardCharsets.UTF_8), signatureBytes, publicKeyBytes))
|
||||||
final Signature signature = new EdDSAEngine(MessageDigest.getInstance(parameterSpec.getHashAlgorithm()));
|
|
||||||
final byte[] rawPublicKeyBytes = new byte[32];
|
|
||||||
System.arraycopy(publicKeyBytes, 10, rawPublicKeyBytes, 0, 32);
|
|
||||||
signature.initVerify(new EdDSAPublicKey(new EdDSAPublicKeySpec(rawPublicKeyBytes, parameterSpec)));
|
|
||||||
signature.update(lines[2].getBytes(StandardCharsets.UTF_8));
|
|
||||||
if (!signature.verify(signatureBytes, 10, 64))
|
|
||||||
return null;
|
|
||||||
} catch (final Exception ignored) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
final Map<String, Sha256Digest> hashes = new HashMap<>();
|
final Map<String, Sha256Digest> hashes = new HashMap<>();
|
||||||
for (final String line : lines[2].split("\n")) {
|
for (final String line : lines[2].split("\n")) {
|
||||||
|
@ -28,7 +28,7 @@ import androidx.annotation.Nullable;
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings({"MagicNumber", "NonConstantFieldWithUpperCaseName", "SuspiciousNameCombination"})
|
@SuppressWarnings({"MagicNumber", "NonConstantFieldWithUpperCaseName", "SuspiciousNameCombination"})
|
||||||
@NonNullForAll
|
@NonNullForAll
|
||||||
final class Curve25519 {
|
public final class Curve25519 {
|
||||||
// Numbers modulo 2^255 - 19 are broken up into ten 26-bit words.
|
// Numbers modulo 2^255 - 19 are broken up into ten 26-bit words.
|
||||||
private static final int NUM_LIMBS_255BIT = 10;
|
private static final int NUM_LIMBS_255BIT = 10;
|
||||||
private static final int NUM_LIMBS_510BIT = 20;
|
private static final int NUM_LIMBS_510BIT = 20;
|
||||||
|
2506
tunnel/src/main/java/com/wireguard/crypto/Ed25519.java
Normal file
2506
tunnel/src/main/java/com/wireguard/crypto/Ed25519.java
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user