From 1bda529e3cf685d5108832ecac7f433c85acb6fd Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Thu, 06 Aug 2026 11:31:31 +0000
Subject: [PATCH] Remove global digestLock serialization in digest password storage schemes (#667)
---
opendj-server-legacy/src/main/java/org/opends/server/util/Crypt.java | 33 ++++++++++++++++++---------------
1 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/util/Crypt.java b/opendj-server-legacy/src/main/java/org/opends/server/util/Crypt.java
index 1391b2e..078f849 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/util/Crypt.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/util/Crypt.java
@@ -13,6 +13,7 @@
*
* Copyright 2008 Sun Microsystems, Inc.
* Portions Copyright 2015 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
@@ -136,18 +137,26 @@
int _iobuf[] = new int[16];
}
- private final SubCrypt _crypt;
+ /**
+ * The working state of the algorithm. setkey(), encrypt() and _crypt() all
+ * scribble on these buffers (and _crypt() returns a reference to _iobuf),
+ * so a per-thread instance is used instead of a shared instance guarded by
+ * a lock: encrypting under a global lock serializes all concurrent {CRYPT}
+ * password operations.
+ */
+ private final ThreadLocal<SubCrypt> _crypt = ThreadLocal.withInitial(() -> {
+ SubCrypt c = new SubCrypt();
+ copy(e, c._E);
+ return c;
+ });
/**
* Constructor.
*/
public Crypt() {
- _crypt = new SubCrypt();
-
- copy(e, _crypt._E);
}
- private void copy(byte[] src, int[] dest) {
+ private static void copy(byte[] src, int[] dest) {
for (int i = 0; i < dest.length; i++) {
dest[i] = src[i];
}
@@ -158,7 +167,7 @@
*/
private void setkey(int[] key)
{
- SubCrypt _c = _crypt;
+ SubCrypt _c = _crypt.get();
/*
* if (_c == null) { _cryptinit(); _c = __crypt; }
@@ -270,7 +279,7 @@
*/
private final void encrypt(int block[], int edflag)
{
- SubCrypt _c = _crypt;
+ SubCrypt _c = _crypt.get();
/*
* First, permute the bits in the input
@@ -369,8 +378,6 @@
}
}
- private Object digestLock = new Object();
-
/**
* Encode the supplied password in unix crypt form with the provided
* salt.
@@ -382,11 +389,7 @@
*/
public byte[] crypt(byte[] pw, byte[] salt)
{
- int[] r;
- synchronized (digestLock)
- {
- r = _crypt(pw, salt);
- }
+ int[] r = _crypt(pw, salt);
//TODO: crypt always returns same size array? So don't mess
// around calculating the number of zeros at the end.
@@ -416,7 +419,7 @@
private int[] _crypt(byte[] pw, byte[] salt)
{
- SubCrypt _c = _crypt;
+ SubCrypt _c = _crypt.get();
Arrays.fill(_c._ablock, 0);
--
Gitblit v1.10.0