11package org .bouncycastle .jsse .provider ;
22
33import java .security .AlgorithmParameters ;
4+ import java .security .GeneralSecurityException ;
45import java .util .ArrayList ;
56import java .util .Collections ;
67import java .util .LinkedHashMap ;
@@ -81,13 +82,19 @@ private enum All
8182 OQS_mlkem1024 (NamedGroup .OQS_mlkem1024 , "ML-KEM" ),
8283 MLKEM512 (NamedGroup .MLKEM512 , "ML-KEM" ),
8384 MLKEM768 (NamedGroup .MLKEM768 , "ML-KEM" ),
84- MLKEM1024 (NamedGroup .MLKEM1024 , "ML-KEM" );
85+ MLKEM1024 (NamedGroup .MLKEM1024 , "ML-KEM" ),
86+
87+ SecP256r1MLKEM768 (NamedGroup .SecP256r1MLKEM768 , "EC" , "ML-KEM" ),
88+ X25519MLKEM768 (NamedGroup .X25519MLKEM768 , "ML-KEM" , "XDH" ),
89+ SecP384r1MLKEM1024 (NamedGroup .SecP384r1MLKEM1024 , "EC" , "ML-KEM" );
8590
8691 private final int namedGroup ;
8792 private final String name ;
8893 private final String text ;
89- private final String jcaAlgorithm ;
90- private final String jcaGroup ;
94+ private final String jcaAlgorithm1 ;
95+ private final String jcaAlgorithm2 ;
96+ private final String jcaGroup1 ;
97+ private final String jcaGroup2 ;
9198 private final boolean char2 ;
9299 private final boolean supportedPost13 ;
93100 private final boolean supportedPre13 ;
@@ -96,17 +103,45 @@ private enum All
96103
97104 private All (int namedGroup , String jcaAlgorithm )
98105 {
106+ if (NamedGroup .refersToASpecificHybrid (namedGroup ))
107+ {
108+ throw new IllegalArgumentException ("Non-hybrid constructor only" );
109+ }
110+
99111 this .namedGroup = namedGroup ;
100112 this .name = NamedGroup .getName (namedGroup );
101113 this .text = NamedGroup .getText (namedGroup );
102- this .jcaAlgorithm = jcaAlgorithm ;
103- this .jcaGroup = NamedGroup .getStandardName (namedGroup );
114+ this .jcaAlgorithm1 = jcaAlgorithm ;
115+ this .jcaAlgorithm2 = null ;
116+ this .jcaGroup1 = NamedGroup .getStandardName (namedGroup );
117+ this .jcaGroup2 = null ;
104118 this .supportedPost13 = NamedGroup .canBeNegotiated (namedGroup , ProtocolVersion .TLSv13 );
105119 this .supportedPre13 = NamedGroup .canBeNegotiated (namedGroup , ProtocolVersion .TLSv12 );
106120 this .char2 = NamedGroup .isChar2Curve (namedGroup );
107121 this .bitsECDH = NamedGroup .getCurveBits (namedGroup );
108122 this .bitsFFDHE = NamedGroup .getFiniteFieldBits (namedGroup );
109123 }
124+
125+ private All (int namedGroup , String jcaAlgorithm1 , String jcaAlgorithm2 )
126+ {
127+ if (!NamedGroup .refersToASpecificHybrid (namedGroup ))
128+ {
129+ throw new IllegalArgumentException ("Hybrid constructor only" );
130+ }
131+
132+ this .namedGroup = namedGroup ;
133+ this .name = NamedGroup .getName (namedGroup );
134+ this .text = NamedGroup .getText (namedGroup );
135+ this .jcaAlgorithm1 = jcaAlgorithm1 ;
136+ this .jcaAlgorithm2 = jcaAlgorithm2 ;
137+ this .jcaGroup1 = NamedGroup .getStandardName (NamedGroup .getHybridFirst (namedGroup ));
138+ this .jcaGroup2 = NamedGroup .getStandardName (NamedGroup .getHybridSecond (namedGroup ));
139+ this .supportedPost13 = NamedGroup .canBeNegotiated (namedGroup , ProtocolVersion .TLSv13 );
140+ this .supportedPre13 = NamedGroup .canBeNegotiated (namedGroup , ProtocolVersion .TLSv12 );
141+ this .char2 = false ;
142+ this .bitsECDH = -1 ;
143+ this .bitsFFDHE = -1 ;
144+ }
110145 }
111146
112147 private static final int [] CANDIDATES_DEFAULT = {
@@ -439,23 +474,37 @@ private static void addNamedGroup(boolean isFipsContext, JcaTlsCrypto crypto, bo
439474
440475 boolean disable = (disableChar2 && all .char2 ) || (disableFFDHE && all .bitsFFDHE > 0 );
441476
442- boolean enabled = !disable && (null != all .jcaGroup ) && crypto .hasNamedGroup (namedGroup );
477+ boolean enabled = !disable && (null != all .jcaGroup1 ) && (null == all .jcaAlgorithm2 || null != all .jcaGroup2 )
478+ && TlsUtils .isSupportedNamedGroup (crypto , namedGroup );
479+
480+ AlgorithmParameters algorithmParameters1 = null ;
481+ AlgorithmParameters algorithmParameters2 = null ;
443482
444- AlgorithmParameters algorithmParameters = null ;
445483 if (enabled )
446484 {
447- // TODO[jsse] Consider also fetching 'jcaAlgorithm'
485+ // TODO[jsse] Consider also fetching 'jcaAlgorithm1', 'jcaAlgorithm2'
486+
448487 try
449488 {
450- algorithmParameters = crypto .getNamedGroupAlgorithmParameters (namedGroup );
489+ if (NamedGroup .refersToASpecificHybrid (namedGroup ))
490+ {
491+ algorithmParameters1 = getAlgorithmParameters (crypto , NamedGroup .getHybridFirst (namedGroup ));
492+ algorithmParameters2 = getAlgorithmParameters (crypto , NamedGroup .getHybridSecond (namedGroup ));
493+ }
494+ else
495+ {
496+ algorithmParameters1 = getAlgorithmParameters (crypto , namedGroup );
497+ }
451498 }
452499 catch (Exception e )
453500 {
454501 enabled = false ;
502+ algorithmParameters1 = null ;
503+ algorithmParameters2 = null ;
455504 }
456505 }
457506
458- NamedGroupInfo namedGroupInfo = new NamedGroupInfo (all , algorithmParameters , enabled );
507+ NamedGroupInfo namedGroupInfo = new NamedGroupInfo (all , algorithmParameters1 , algorithmParameters2 , enabled );
459508
460509 if (null != ng .put (namedGroup , namedGroupInfo ))
461510 {
@@ -531,6 +580,12 @@ private static Map<Integer, NamedGroupInfo> createIndex(boolean isFipsContext, J
531580 return ng ;
532581 }
533582
583+ private static AlgorithmParameters getAlgorithmParameters (JcaTlsCrypto crypto , int namedGroup )
584+ throws GeneralSecurityException
585+ {
586+ return crypto .getNamedGroupAlgorithmParameters (namedGroup );
587+ }
588+
534589 private static int getNamedGroupByName (String name )
535590 {
536591 for (All all : All .values ())
@@ -589,13 +644,16 @@ private static boolean hasAnyECDSA(Map<Integer, NamedGroupInfo> local)
589644 }
590645
591646 private final All all ;
592- private final AlgorithmParameters algorithmParameters ;
647+ private final AlgorithmParameters algorithmParameters1 ;
648+ private final AlgorithmParameters algorithmParameters2 ;
593649 private final boolean enabled ;
594650
595- NamedGroupInfo (All all , AlgorithmParameters algorithmParameters , boolean enabled )
651+ NamedGroupInfo (All all , AlgorithmParameters algorithmParameters1 , AlgorithmParameters algorithmParameters2 ,
652+ boolean enabled )
596653 {
597654 this .all = all ;
598- this .algorithmParameters = algorithmParameters ;
655+ this .algorithmParameters1 = algorithmParameters1 ;
656+ this .algorithmParameters2 = algorithmParameters2 ;
599657 this .enabled = enabled ;
600658 }
601659
@@ -609,16 +667,6 @@ int getBitsFFDHE()
609667 return all .bitsFFDHE ;
610668 }
611669
612- String getJcaAlgorithm ()
613- {
614- return all .jcaAlgorithm ;
615- }
616-
617- String getJcaGroup ()
618- {
619- return all .jcaGroup ;
620- }
621-
622670 int getNamedGroup ()
623671 {
624672 return all .namedGroup ;
@@ -656,7 +704,21 @@ private boolean isPermittedBy(BCAlgorithmConstraints algorithmConstraints)
656704 {
657705 Set <BCCryptoPrimitive > primitives = JsseUtils .KEY_AGREEMENT_CRYPTO_PRIMITIVES_BC ;
658706
659- return algorithmConstraints .permits (primitives , getJcaGroup (), null )
660- && algorithmConstraints .permits (primitives , getJcaAlgorithm (), algorithmParameters );
707+ if (!algorithmConstraints .permits (primitives , all .jcaGroup1 , null ) ||
708+ !algorithmConstraints .permits (primitives , all .jcaAlgorithm1 , algorithmParameters1 ))
709+ {
710+ return false ;
711+ }
712+
713+ if (all .jcaAlgorithm2 != null )
714+ {
715+ if (!algorithmConstraints .permits (primitives , all .jcaGroup2 , null ) ||
716+ !algorithmConstraints .permits (primitives , all .jcaAlgorithm2 , algorithmParameters2 ))
717+ {
718+ return false ;
719+ }
720+ }
721+
722+ return true ;
661723 }
662724}
0 commit comments