Skip to content

Commit

Permalink
Merge remote-tracking branch 'bertm/simplify-sha256' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneBab committed Nov 11, 2024
2 parents 9f625ad + 7304175 commit 2418270
Show file tree
Hide file tree
Showing 22 changed files with 204 additions and 340 deletions.
8 changes: 2 additions & 6 deletions src/freenet/client/Metadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -737,9 +737,7 @@ public static byte[] getCryptoKey(byte[] hash) {
MessageDigest md = SHA256.getMessageDigest();
md.update(hash);
md.update(SPLITKEY);
byte[] buf = md.digest();
SHA256.returnMessageDigest(md);
return buf;
return md.digest();
}

public static byte[] getCrossSegmentSeed(HashResult[] hashes, byte[] hashThisLayerOnly) {
Expand All @@ -758,9 +756,7 @@ public static byte[] getCrossSegmentSeed(byte[] hash) {
MessageDigest md = SHA256.getMessageDigest();
md.update(hash);
md.update(CROSS_SEGMENT_SEED);
byte[] buf = md.digest();
SHA256.returnMessageDigest(md);
return buf;
return md.digest();
}

/**
Expand Down
9 changes: 3 additions & 6 deletions src/freenet/client/async/KeyListenerTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@
import static java.lang.String.format;

import java.security.MessageDigest;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.List;

import freenet.crypt.RandomSource;
import freenet.crypt.SHA256;
import freenet.keys.Key;
import freenet.keys.KeyBlock;
import freenet.keys.NodeSSK;
import freenet.node.SendableGet;
import freenet.node.SendableRequest;
import freenet.support.ByteArrayWrapper;
import freenet.support.LogThresholdCallback;
import freenet.support.Logger;
Expand Down Expand Up @@ -469,9 +468,7 @@ private byte[] saltKey(byte[] key) {
MessageDigest md = SHA256.getMessageDigest();
md.update(key);
md.update(globalSalt);
byte[] ret = md.digest();
SHA256.returnMessageDigest(md);
return ret;
return md.digest();
}

protected void hintGlobalSalt(byte[] globalSalt2) {
Expand Down
4 changes: 1 addition & 3 deletions src/freenet/client/async/SplitFileFetcherKeyListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,7 @@ private byte[] localSaltKey(Key key) {
MessageDigest md = SHA256.getMessageDigest();
md.update(key.getRoutingKey());
md.update(localSalt);
byte[] ret = md.digest();
SHA256.returnMessageDigest(md);
return ret;
return md.digest();
}

/** The segment bloom filters should only need to be written ONCE, and can all be written at
Expand Down
2 changes: 0 additions & 2 deletions src/freenet/clients/fcp/ClientPut.java
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,13 @@ public ClientPut(FCPConnectionHandler handler, ClientPutMessage message, FCPServ
is = data.getInputStream();
SHA256.hash(is, md);
} catch (IOException e) {
SHA256.returnMessageDigest(md);
Logger.error(this, "Got IOE: " + e.getMessage(), e);
throw new MessageInvalidException(ProtocolErrorMessage.COULD_NOT_READ_FILE,
"Unable to access file: " + e, identifier, global);
} finally {
Closer.close(is);
}
foundHash = md.digest();
SHA256.returnMessageDigest(md);

if(logMINOR) Logger.minor(this, "FileHash result : we found " + Base64.encode(foundHash) + " and were given " + Base64.encode(saltedHash) + '.');

Expand Down
47 changes: 19 additions & 28 deletions src/freenet/crypt/HashType.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;

import org.bitpedia.util.TigerTree;

import freenet.support.Logger;

public enum HashType {
// warning: keep in sync with Util.mdProviders!
SHA1(1, 20),
MD5(2, 16),
SHA1(1, "SHA1", 20),
MD5(2, "MD5", 16),
SHA256(4, "SHA-256", 32),
SHA384(8, "SHA-384", 48),
SHA512(16, "SHA-512", 64),
Expand All @@ -26,41 +25,33 @@ public enum HashType {
public final String javaName;
public final int hashLength;

private HashType(int bitmask, int hashLength) {
this.bitmask = bitmask;
this.javaName = super.name();
this.hashLength = hashLength;
}
private final Provider provider;

private HashType(int bitmask, String name, int hashLength) {
HashType(int bitmask, String name, int hashLength) {
this.bitmask = bitmask;
this.javaName = name;
this.hashLength = hashLength;
this.provider = javaName != null ? Util.mdProviders.get(javaName) : null;
}

public final MessageDigest get() {
if(javaName == null) {
if(this.name().equals("ED2K"))
return new Ed2MessageDigest();
if(this.name().equals("TTH"))
return new TigerTree();
if (this == ED2K) {
return new Ed2MessageDigest();
}
if (this == TTH) {
return new TigerTree();
}
if(name().equals("SHA256")) {
// Use the pool
return freenet.crypt.SHA256.getMessageDigest();
} else {
try {
return MessageDigest.getInstance(javaName, Util.mdProviders.get(javaName));
} catch (NoSuchAlgorithmException e) {
Logger.error(HashType.class, "Internal error; please report:", e);
}
return null;
try {
return MessageDigest.getInstance(javaName, provider);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Unsupported digest algorithm " + javaName, e);
}
}

/**
* @deprecated message digests are no longer pooled, there is no need to recycle them
*/
@Deprecated
public final void recycle(MessageDigest md) {
if(this.equals(SHA256)) {
freenet.crypt.SHA256.returnMessageDigest(md);
} // Else no pooling.
}
}
57 changes: 7 additions & 50 deletions src/freenet/crypt/SHA256.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,14 @@ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.tanukisoftware.wrapper.WrapperManager;

import freenet.node.Node;
import freenet.node.NodeInitException;
import freenet.support.Logger;
import freenet.support.io.Closer;

/**
* @author Jeroen C. van Gelderen ([email protected])
*/
public class SHA256 {
/** Size (in bytes) of this hash */
private static final int HASH_SIZE = 32;
private static final Queue<SoftReference<MessageDigest>> digests = new ConcurrentLinkedQueue<>();

/**
* It won't reset the Message Digest for you!
Expand All @@ -78,57 +65,27 @@ public static void hash(InputStream is, MessageDigest md) throws IOException {
}
}

private static final Provider mdProvider = Util.mdProviders.get("SHA-256");

/**
* Create a new SHA-256 MessageDigest
* Either succeed or stop the node.
*/
public static MessageDigest getMessageDigest() {
try {
SoftReference<MessageDigest> item = null;
while (((item = digests.poll()) != null)) {
MessageDigest md = item.get();
if (md != null) {
return md;
}
}
return MessageDigest.getInstance("SHA-256", mdProvider);
} catch(NoSuchAlgorithmException e2) {
//TODO: maybe we should point to a HOWTO for freejvms
Logger.error(Node.class, "Check your JVM settings especially the JCE!" + e2);
System.err.println("Check your JVM settings especially the JCE!" + e2);
e2.printStackTrace();
}
WrapperManager.stop(NodeInitException.EXIT_CRAPPY_JVM);
throw new RuntimeException();
return HashType.SHA256.get();
}

/**
* Return a MessageDigest to the pool.
* Must be SHA-256 !
* No-op function retained for backwards compatibility.
*
* @deprecated message digests are no longer pooled, there is no need to return them
*/
@Deprecated
public static void returnMessageDigest(MessageDigest md256) {
if(md256 == null)
return;
String algo = md256.getAlgorithm();
if(!(algo.equals("SHA-256") || algo.equals("SHA256")))
throw new IllegalArgumentException("Should be SHA-256 but is " + algo);
md256.reset();
digests.add(new SoftReference<>(md256));
}

public static byte[] digest(byte[] data) {
MessageDigest md = null;
try {
md = getMessageDigest();
return md.digest(data);
} finally {
returnMessageDigest(md);
}
return getMessageDigest().digest(data);
}

public static int getDigestLength() {
return HASH_SIZE;
return HashType.SHA256.hashLength;
}
}
1 change: 0 additions & 1 deletion src/freenet/keys/CHKBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ public CHKBlock(byte[] data2, byte[] header2, NodeCHK key, boolean verify, byte
md.update(headers);
md.update(data);
byte[] hash = md.digest();
SHA256.returnMessageDigest(md);
if(key == null) {
chk = new NodeCHK(hash, cryptoAlgorithm);
} else {
Expand Down
24 changes: 8 additions & 16 deletions src/freenet/keys/ClientCHKBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@
import java.security.Provider;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import freenet.crypt.BlockCipher;
import freenet.crypt.CTRBlockCipher;
import freenet.crypt.JceLoader;
Expand All @@ -33,6 +27,11 @@
import freenet.support.io.ArrayBucketFactory;
import freenet.support.io.BucketTools;
import freenet.support.math.MersenneTwister;
import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
* @author amphibian
Expand Down Expand Up @@ -142,7 +141,6 @@ public Bucket decodeOld(BucketFactory bf, int maxLength, boolean dontCompress) t
byte[] dkey = key.cryptoKey;
// Check: IV == hash of decryption key
byte[] predIV = md256.digest(dkey);
SHA256.returnMessageDigest(md256); md256 = null;
// Extract the IV
byte[] iv = Arrays.copyOf(hbuf, 32);
if(!Arrays.equals(iv, predIV))
Expand Down Expand Up @@ -496,9 +494,7 @@ public static ClientCHKBlock encodeNew(byte[] data, int dataLength, MessageDiges
// Now calculate the final hash
md256.update(header);
byte[] finalHash = md256.digest(cdata);

SHA256.returnMessageDigest(md256);


// Now convert it into a ClientCHK
ClientCHK finalKey = new ClientCHK(finalHash, encKey, asMetadata, cryptoAlgorithm, compressionAlgorithm);

Expand Down Expand Up @@ -570,9 +566,7 @@ public static ClientCHKBlock encodeNewNoJCA(byte[] data, int dataLength, Message
// Now calculate the final hash
md256.update(header);
byte[] finalHash = md256.digest(cdata);

SHA256.returnMessageDigest(md256);


// Now convert it into a ClientCHK
ClientCHK finalKey = new ClientCHK(finalHash, encKey, asMetadata, cryptoAlgorithm, compressionAlgorithm);

Expand Down Expand Up @@ -631,9 +625,7 @@ public static ClientCHKBlock innerEncode(byte[] data, int dataLength, MessageDig
// Now calculate the final hash
md256.update(header);
byte[] finalHash = md256.digest(data);

SHA256.returnMessageDigest(md256);


// Now convert it into a ClientCHK
key = new ClientCHK(finalHash, encKey, asMetadata, cryptoAlgorithm, compressionAlgorithm);

Expand Down
24 changes: 10 additions & 14 deletions src/freenet/keys/ClientKSK.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

/** A KSK. We know the private key from the keyword, so this can be both
* requested and inserted. */

import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

import freenet.support.math.MersenneTwister;

import freenet.crypt.DSAPrivateKey;
import freenet.crypt.DSAPublicKey;
import freenet.crypt.Global;
import freenet.crypt.SHA256;
import freenet.support.math.MersenneTwister;

public class ClientKSK extends InsertableClientSSK {

Expand Down Expand Up @@ -44,19 +44,15 @@ public static InsertableClientSSK create(FreenetURI uri) {

public static ClientKSK create(String keyword) {
MessageDigest md256 = SHA256.getMessageDigest();
byte[] keywordHash = md256.digest(keyword.getBytes(StandardCharsets.UTF_8));
MersenneTwister mt = new MersenneTwister(keywordHash);
DSAPrivateKey privKey = new DSAPrivateKey(Global.DSAgroupBigA, mt);
DSAPublicKey pubKey = new DSAPublicKey(Global.DSAgroupBigA, privKey);
byte[] pubKeyHash = md256.digest(pubKey.asBytes());
try {
byte[] keywordHash = md256.digest(keyword.getBytes(StandardCharsets.UTF_8));
MersenneTwister mt = new MersenneTwister(keywordHash);
DSAPrivateKey privKey = new DSAPrivateKey(Global.DSAgroupBigA, mt);
DSAPublicKey pubKey = new DSAPublicKey(Global.DSAgroupBigA, privKey);
byte[] pubKeyHash = md256.digest(pubKey.asBytes());
try {
return new ClientKSK(keyword, pubKeyHash, pubKey, privKey, keywordHash);
} catch (MalformedURLException e) {
throw new Error(e);
}
} finally {
SHA256.returnMessageDigest(md256);
return new ClientKSK(keyword, pubKeyHash, pubKey, privKey, keywordHash);
} catch (MalformedURLException e) {
throw new Error(e);
}
}

Expand Down
Loading

0 comments on commit 2418270

Please sign in to comment.