Skip to content

Commit 7450b06

Browse files
Adding support for injected algorithms (via InjectionPoint) to the BC PQC provider. PQC algorithms now can be loaded without reflection (useful when compiling with GraalVM native-image).
1 parent c433374 commit 7450b06

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java

+26-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
1818
import org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
1919
import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
20+
import org.bouncycastle.tls.injection.InjectionPoint;
2021

2122
public class BouncyCastlePQCProvider
2223
extends Provider
@@ -43,6 +44,19 @@ public class BouncyCastlePQCProvider
4344
"Dilithium", "NTRUPrime", "BIKE", "HQC", "Rainbow"
4445
};
4546

47+
/**
48+
* #tls-injection
49+
* ALGORITHM_MAPPING_CLASSES contains real classes corresponding to the names given in ALGORITHMS.
50+
* We rely on ALGORITHM_MAPPING_CLASSES when we are unable to load classes by names via reflection
51+
* (important, since we cannot rely fully on reflection in NativeImage from GraalVM).
52+
* #pqc-tls
53+
*/
54+
private static final Class<?>[] ALGORITHM_MAPPING_CLASSES = {
55+
SPHINCS.Mappings.class, LMS.Mappings.class, NH.Mappings.class, XMSS.Mappings.class, SPHINCSPlus.Mappings.class,
56+
CMCE.Mappings.class, Frodo.Mappings.class, SABER.Mappings.class, Picnic.Mappings.class, NTRU.Mappings.class, Falcon.Mappings.class, Kyber.Mappings.class,
57+
Dilithium.Mappings.class, NTRUPrime.Mappings.class, BIKE.Mappings.class, HQC.Mappings.class, Rainbow.Mappings.class
58+
};
59+
4660
/**
4761
* Construct a new provider. This should only be required when
4862
* using runtime registration of the provider using the
@@ -71,21 +85,31 @@ private void loadAlgorithms(String packageName, String[] names)
7185
{
7286
for (int i = 0; i != names.length; i++)
7387
{
74-
Class clazz = loadClass(BouncyCastlePQCProvider.class, packageName + names[i] + "$Mappings");
88+
Class clazz;
89+
if (i<ALGORITHM_MAPPING_CLASSES.length && ALGORITHM_MAPPING_CLASSES[i].getSimpleName().equals(ALGORITHMS[i])) {
90+
// if ALGORITHM_CLASSES[i] indeed corresponds to ALGORITHM[i], we do not use reflection #pqc-tls
91+
clazz = ALGORITHM_MAPPING_CLASSES[i];
92+
}
93+
else
94+
clazz = loadClass(BouncyCastlePQCProvider.class, packageName + names[i] + "$Mappings");
7595

7696
if (clazz != null)
7797
{
7898
try
7999
{
80-
((AlgorithmProvider)clazz.newInstance()).configure(this);
100+
((AlgorithmProvider)clazz.getConstructor().newInstance()).configure(this);
101+
// ^^^ replaces deprecated: ((AlgorithmProvider)clazz.newInstance()).configure(this);
81102
}
82103
catch (Exception e)
83104
{ // this should never ever happen!!
84105
throw new InternalError("cannot create instance of "
85106
+ packageName + names[i] + "$Mappings : " + e);
86107
}
87108
}
109+
88110
}
111+
// Add also injected algorithms to our provider: #tls-injection
112+
InjectionPoint.configureProvider(this);
89113
}
90114

91115
public void setParameter(String parameterName, Object parameter)

0 commit comments

Comments
 (0)