1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.gordianknot.impl.jca;
18
19 import io.github.tonywasher.joceanus.gordianknot.api.agree.spec.GordianAgreementKDF;
20 import io.github.tonywasher.joceanus.gordianknot.api.agree.spec.GordianAgreementType;
21 import io.github.tonywasher.joceanus.gordianknot.api.base.GordianException;
22 import io.github.tonywasher.joceanus.gordianknot.api.base.GordianLength;
23 import io.github.tonywasher.joceanus.gordianknot.api.cipher.spec.GordianSymKeyType;
24 import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPair;
25 import io.github.tonywasher.joceanus.gordianknot.api.keypair.spec.GordianKeyPairSpec;
26 import io.github.tonywasher.joceanus.gordianknot.api.keypair.spec.GordianKeyPairType;
27 import io.github.tonywasher.joceanus.gordianknot.impl.core.agree.GordianCoreAgreementEngine;
28 import io.github.tonywasher.joceanus.gordianknot.impl.core.agree.GordianCoreAgreementFactory;
29 import io.github.tonywasher.joceanus.gordianknot.impl.core.base.GordianBaseData;
30 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianCryptoException;
31 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianDataException;
32 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianPrivateKey;
33 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianPublicKey;
34 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.agree.GordianCoreAgreementSpec;
35 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreKeyPairSpec;
36 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreNTRUPrimeSpec;
37 import io.github.tonywasher.joceanus.gordianknot.impl.jca.JcaKeyPair.JcaPrivateKey;
38 import io.github.tonywasher.joceanus.gordianknot.impl.jca.JcaKeyPair.JcaPublicKey;
39 import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
40 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
41 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
42 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
43 import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
44 import org.bouncycastle.jcajce.spec.DHUParameterSpec;
45 import org.bouncycastle.jcajce.spec.KEMExtractSpec;
46 import org.bouncycastle.jcajce.spec.KEMGenerateSpec;
47 import org.bouncycastle.jcajce.spec.MQVParameterSpec;
48 import org.bouncycastle.jcajce.spec.SM2KeyExchangeSpec;
49 import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
50
51 import javax.crypto.KeyAgreement;
52 import javax.crypto.KeyGenerator;
53 import java.security.InvalidAlgorithmParameterException;
54 import java.security.InvalidKeyException;
55 import java.security.NoSuchAlgorithmException;
56 import java.security.Provider;
57 import java.security.PublicKey;
58
59
60
61
62 public final class JcaAgreement {
63
64
65
66 private static final String ERR_AGREEMENT = "Failed Agreement";
67
68
69
70
71 private JcaAgreement() {
72 }
73
74
75
76
77 public static class JcaPostQuantumEngine
78 extends JcaAgreementBase {
79
80
81
82 private final KeyGenerator theGenerator;
83
84
85
86
87
88
89
90
91 JcaPostQuantumEngine(final GordianCoreAgreementFactory pFactory,
92 final GordianCoreAgreementSpec pSpec,
93 final KeyGenerator pGenerator) throws GordianException {
94
95 super(pFactory, pSpec);
96
97
98 theGenerator = pGenerator;
99 }
100
101 @Override
102 public void buildClientHello() throws GordianException {
103
104 try {
105
106 final JcaPublicKey myPublic = (JcaPublicKey) getPublicKey(getServerKeyPair());
107 final KEMGenerateSpec mySpec = new KEMGenerateSpec.Builder(myPublic.getPublicKey(),
108 GordianSymKeyType.AES.toString(), GordianLength.LEN_256.getLength()).withKdfAlgorithm(derivationAlgorithmId()).build();
109 theGenerator.init(mySpec, getRandom());
110 final SecretKeyWithEncapsulation mySecret = (SecretKeyWithEncapsulation) theGenerator.generateKey();
111
112
113 setEncapsulated(mySecret.getEncapsulation());
114
115
116 storeSecret(mySecret.getEncoded());
117
118 } catch (InvalidAlgorithmParameterException e) {
119 throw new GordianCryptoException(ERR_AGREEMENT, e);
120 }
121 }
122
123 @Override
124 public void processClientHello() throws GordianException {
125
126 try {
127
128 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getServerKeyPair());
129 final KEMExtractSpec mySpec = new KEMExtractSpec.Builder(myPrivate.getPrivateKey(), getEncapsulated(),
130 GordianSymKeyType.AES.toString(), GordianLength.LEN_256.getLength()).withKdfAlgorithm(derivationAlgorithmId()).build();
131 theGenerator.init(mySpec);
132
133
134 final SecretKeyWithEncapsulation mySecret = (SecretKeyWithEncapsulation) theGenerator.generateKey();
135 storeSecret(mySecret.getEncoded());
136
137 } catch (InvalidAlgorithmParameterException e) {
138 throw new GordianCryptoException(ERR_AGREEMENT, e);
139 }
140 }
141 }
142
143
144
145
146 public static class JcaNewHopeEngine
147 extends JcaAgreementBase {
148
149
150
151 private final KeyAgreement theAgreement;
152
153
154
155
156
157
158
159
160 JcaNewHopeEngine(final GordianCoreAgreementFactory pFactory,
161 final GordianCoreAgreementSpec pSpec,
162 final KeyAgreement pAgreement) throws GordianException {
163
164 super(pFactory, pSpec);
165
166
167 theAgreement = pAgreement;
168 }
169
170 @Override
171 public void buildClientHello() throws GordianException {
172
173 try {
174
175 theAgreement.init(null, getRandom());
176 final JcaPublicKey myTarget = (JcaPublicKey) getPublicKey(getServerKeyPair());
177 final PublicKey myKey = (PublicKey) theAgreement.doPhase(myTarget.getPublicKey(), true);
178
179
180 final GordianKeyPairSpec mySpec = getSpec().getKeyPairSpec();
181 final JcaPublicKey myPublic = new JcaPublicKey(mySpec, myKey);
182 final JcaKeyPair myEphemeral = new JcaKeyPair(myPublic);
183 setClientEphemeralAsEncapsulated(myEphemeral);
184
185
186 storeSecret(theAgreement.generateSecret());
187
188 } catch (InvalidKeyException e) {
189 throw new GordianCryptoException(ERR_AGREEMENT, e);
190 }
191 }
192
193 @Override
194 public void processClientHello() throws GordianException {
195
196 try {
197
198 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getServerKeyPair());
199 final JcaPublicKey myPublic = (JcaPublicKey) getPublicKey(getClientEphemeral());
200 theAgreement.init(myPrivate.getPrivateKey());
201 theAgreement.doPhase(myPublic.getPublicKey(), true);
202
203
204 storeSecret(theAgreement.generateSecret());
205
206 } catch (InvalidKeyException e) {
207 throw new GordianCryptoException(ERR_AGREEMENT, e);
208 }
209 }
210 }
211
212
213
214
215 public static class JcaAnonEngine
216 extends JcaAgreementBase {
217
218
219
220 private KeyAgreement theAgreement;
221
222
223
224
225
226
227
228
229 JcaAnonEngine(final GordianCoreAgreementFactory pFactory,
230 final GordianCoreAgreementSpec pSpec,
231 final KeyAgreement pAgreement) throws GordianException {
232
233 super(pFactory, pSpec);
234
235
236 theAgreement = pAgreement;
237 }
238
239 @Override
240 public void buildClientHello() throws GordianException {
241
242 try {
243
244 final JcaPublicKey myPublic = (JcaPublicKey) getPublicKey(getServerKeyPair());
245 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getClientEphemeral());
246 theAgreement = adjustAgreement(theAgreement, getServerKeyPair());
247
248
249 initAgreement(theAgreement, myPrivate);
250 theAgreement.doPhase(myPublic.getPublicKey(), true);
251 storeSecret(theAgreement.generateSecret());
252
253 } catch (InvalidKeyException e) {
254 throw new GordianCryptoException(ERR_AGREEMENT, e);
255 }
256 }
257
258 @Override
259 public void processClientHello() throws GordianException {
260
261 try {
262
263 final JcaPublicKey myPublic = (JcaPublicKey) getPublicKey(getClientEphemeral());
264 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getServerKeyPair());
265 theAgreement = adjustAgreement(theAgreement, getServerKeyPair());
266
267
268 initAgreement(theAgreement, myPrivate);
269 theAgreement.doPhase(myPublic.getPublicKey(), true);
270 storeSecret(theAgreement.generateSecret());
271
272 } catch (InvalidKeyException e) {
273 throw new GordianCryptoException(ERR_AGREEMENT, e);
274 }
275 }
276 }
277
278
279
280
281 public static class JcaBasicEngine
282 extends JcaAgreementBase {
283
284
285
286 private KeyAgreement theAgreement;
287
288
289
290
291
292
293
294
295 JcaBasicEngine(final GordianCoreAgreementFactory pFactory,
296 final GordianCoreAgreementSpec pSpec,
297 final KeyAgreement pAgreement) throws GordianException {
298
299 super(pFactory, pSpec);
300
301
302 theAgreement = pAgreement;
303 }
304
305 @Override
306 public void processClientHello() throws GordianException {
307
308 try {
309
310 final JcaPublicKey myPublic = (JcaPublicKey) getPublicKey(getClientKeyPair());
311 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getServerKeyPair());
312 theAgreement = adjustAgreement(theAgreement, getServerKeyPair());
313
314
315 initAgreement(theAgreement, myPrivate);
316 theAgreement.doPhase(myPublic.getPublicKey(), true);
317 storeSecret(theAgreement.generateSecret());
318
319 } catch (InvalidKeyException e) {
320 throw new GordianCryptoException(ERR_AGREEMENT, e);
321 }
322 }
323
324 @Override
325 public void processServerHello() throws GordianException {
326
327 try {
328
329 final JcaPublicKey myPublic = (JcaPublicKey) getPublicKey(getServerKeyPair());
330 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getClientKeyPair());
331 theAgreement = adjustAgreement(theAgreement, getServerKeyPair());
332
333
334 initAgreement(theAgreement, myPrivate);
335 theAgreement.doPhase(myPublic.getPublicKey(), true);
336 storeSecret(theAgreement.generateSecret());
337
338 } catch (InvalidKeyException e) {
339 throw new GordianCryptoException(ERR_AGREEMENT, e);
340 }
341 }
342 }
343
344
345
346
347 public static class JcaUnifiedEngine
348 extends JcaAgreementBase {
349
350
351
352 private KeyAgreement theAgreement;
353
354
355
356
357
358
359
360
361 JcaUnifiedEngine(final GordianCoreAgreementFactory pFactory,
362 final GordianCoreAgreementSpec pSpec,
363 final KeyAgreement pAgreement) throws GordianException {
364
365 super(pFactory, pSpec);
366
367
368 theAgreement = pAgreement;
369 }
370
371 @Override
372 public void processClientHello() throws GordianException {
373
374 try {
375
376 final JcaPublicKey myClientPublic = (JcaPublicKey) getPublicKey(getClientKeyPair());
377 final JcaPublicKey myClientEphPublic = (JcaPublicKey) getPublicKey(getClientEphemeral());
378 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getServerKeyPair());
379 final JcaPublicKey myEphPublic = (JcaPublicKey) getPublicKey(getServerEphemeral());
380 final JcaPrivateKey myEphPrivate = (JcaPrivateKey) getPrivateKey(getServerEphemeral());
381 theAgreement = adjustAgreement(theAgreement, getServerKeyPair());
382
383
384 final DHUParameterSpec myParams = new DHUParameterSpec(myEphPublic.getPublicKey(),
385 myEphPrivate.getPrivateKey(), myClientEphPublic.getPublicKey(), getAdditional());
386 theAgreement.init(myPrivate.getPrivateKey(), myParams, getRandom());
387 theAgreement.doPhase(myClientPublic.getPublicKey(), true);
388 storeSecret(theAgreement.generateSecret());
389
390 } catch (InvalidKeyException
391 | InvalidAlgorithmParameterException e) {
392 throw new GordianCryptoException(ERR_AGREEMENT, e);
393 }
394 }
395
396 @Override
397 public void processServerHello() throws GordianException {
398
399 try {
400
401 final JcaPublicKey myServerPublic = (JcaPublicKey) getPublicKey(getServerKeyPair());
402 final JcaPublicKey myServerEphPublic = (JcaPublicKey) getPublicKey(getServerEphemeral());
403 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getClientKeyPair());
404 final JcaPublicKey myEphPublic = (JcaPublicKey) getPublicKey(getClientEphemeral());
405 final JcaPrivateKey myEphPrivate = (JcaPrivateKey) getPrivateKey(getClientEphemeral());
406 theAgreement = adjustAgreement(theAgreement, getServerKeyPair());
407
408
409 final DHUParameterSpec myParams = new DHUParameterSpec(myEphPublic.getPublicKey(),
410 myEphPrivate.getPrivateKey(), myServerEphPublic.getPublicKey(), getAdditional());
411 theAgreement.init(myPrivate.getPrivateKey(), myParams);
412 theAgreement.doPhase(myServerPublic.getPublicKey(), true);
413 storeSecret(theAgreement.generateSecret());
414
415 } catch (InvalidKeyException
416 | InvalidAlgorithmParameterException e) {
417 throw new GordianCryptoException(ERR_AGREEMENT, e);
418 }
419 }
420 }
421
422
423
424
425 public static class JcaMQVEngine
426 extends JcaAgreementBase {
427
428
429
430 private final KeyAgreement theAgreement;
431
432
433
434
435
436
437
438
439 JcaMQVEngine(final GordianCoreAgreementFactory pFactory,
440 final GordianCoreAgreementSpec pSpec,
441 final KeyAgreement pAgreement) throws GordianException {
442
443 super(pFactory, pSpec);
444
445
446 theAgreement = pAgreement;
447 }
448
449 @Override
450 public void processClientHello() throws GordianException {
451
452 try {
453
454 final JcaPublicKey myClientPublic = (JcaPublicKey) getPublicKey(getClientKeyPair());
455 final JcaPublicKey myClientEphPublic = (JcaPublicKey) getPublicKey(getClientEphemeral());
456 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getServerKeyPair());
457 final JcaPublicKey myEphPublic = (JcaPublicKey) getPublicKey(getServerEphemeral());
458 final JcaPrivateKey myEphPrivate = (JcaPrivateKey) getPrivateKey(getServerEphemeral());
459
460
461 final MQVParameterSpec myParams = new MQVParameterSpec(myEphPublic.getPublicKey(),
462 myEphPrivate.getPrivateKey(), myClientEphPublic.getPublicKey(), getAdditional());
463 theAgreement.init(myPrivate.getPrivateKey(), myParams, getRandom());
464 theAgreement.doPhase(myClientPublic.getPublicKey(), true);
465 storeSecret(theAgreement.generateSecret());
466
467 } catch (InvalidKeyException
468 | InvalidAlgorithmParameterException e) {
469 throw new GordianCryptoException(ERR_AGREEMENT, e);
470 }
471 }
472
473 @Override
474 public void processServerHello() throws GordianException {
475
476 try {
477
478 final JcaPublicKey myServerPublic = (JcaPublicKey) getPublicKey(getServerKeyPair());
479 final JcaPublicKey myServerEphPublic = (JcaPublicKey) getPublicKey(getServerEphemeral());
480 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getClientKeyPair());
481 final JcaPublicKey myEphPublic = (JcaPublicKey) getPublicKey(getClientEphemeral());
482 final JcaPrivateKey myEphPrivate = (JcaPrivateKey) getPrivateKey(getClientEphemeral());
483
484
485 final MQVParameterSpec myParams = new MQVParameterSpec(myEphPublic.getPublicKey(),
486 myEphPrivate.getPrivateKey(), myServerEphPublic.getPublicKey(), getAdditional());
487 theAgreement.init(myPrivate.getPrivateKey(), myParams);
488 theAgreement.doPhase(myServerPublic.getPublicKey(), true);
489 storeSecret(theAgreement.generateSecret());
490
491 } catch (InvalidKeyException
492 | InvalidAlgorithmParameterException e) {
493 throw new GordianCryptoException(ERR_AGREEMENT, e);
494 }
495 }
496 }
497
498
499
500
501 public static class JcaSM2Engine
502 extends JcaAgreementBase {
503
504
505
506 private final KeyAgreement theAgreement;
507
508
509
510
511
512
513
514
515 JcaSM2Engine(final GordianCoreAgreementFactory pFactory,
516 final GordianCoreAgreementSpec pSpec,
517 final KeyAgreement pAgreement) throws GordianException {
518
519 super(pFactory, pSpec);
520
521
522 theAgreement = pAgreement;
523 }
524
525 @Override
526 public void processClientHello() throws GordianException {
527
528 try {
529
530 final JcaPublicKey myClientPublic = (JcaPublicKey) getPublicKey(getClientKeyPair());
531 final JcaPublicKey myClientEphPublic = (JcaPublicKey) getPublicKey(getClientEphemeral());
532 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getServerKeyPair());
533 final JcaPrivateKey myEphPrivate = (JcaPrivateKey) getPrivateKey(getServerEphemeral());
534
535
536 final byte[] myClientID = getClientName() == null ? EMPTY : getClientName();
537 final byte[] myServerID = getServerName() == null ? EMPTY : getServerName();
538
539
540 final SM2KeyExchangeSpec mySpec = new SM2KeyExchangeSpec(false,
541 myEphPrivate.getPrivateKey(), myClientEphPublic.getPublicKey(), myServerID, myClientID);
542 theAgreement.init(myPrivate.getPrivateKey(), mySpec);
543 theAgreement.doPhase(myClientPublic.getPublicKey(), true);
544 storeSecret(theAgreement.generateSecret());
545
546 } catch (InvalidKeyException
547 | InvalidAlgorithmParameterException e) {
548 throw new GordianCryptoException(ERR_AGREEMENT, e);
549 }
550 }
551
552 @Override
553 public void processServerHello() throws GordianException {
554
555 try {
556
557 final JcaPublicKey myServerPublic = (JcaPublicKey) getPublicKey(getServerKeyPair());
558 final JcaPublicKey myServerEphPublic = (JcaPublicKey) getPublicKey(getServerEphemeral());
559 final JcaPrivateKey myPrivate = (JcaPrivateKey) getPrivateKey(getClientKeyPair());
560 final JcaPrivateKey myEphPrivate = (JcaPrivateKey) getPrivateKey(getClientEphemeral());
561
562
563 final byte[] myClientID = getClientName() == null ? EMPTY : getClientName();
564 final byte[] myServerID = getServerName() == null ? EMPTY : getServerName();
565
566
567 final SM2KeyExchangeSpec mySpec = new SM2KeyExchangeSpec(true,
568 myEphPrivate.getPrivateKey(), myServerEphPublic.getPublicKey(), myClientID, myServerID);
569 theAgreement.init(myPrivate.getPrivateKey(), mySpec);
570 theAgreement.doPhase(myServerPublic.getPublicKey(), true);
571 storeSecret(theAgreement.generateSecret());
572
573 } catch (InvalidKeyException
574 | InvalidAlgorithmParameterException e) {
575 throw new GordianCryptoException(ERR_AGREEMENT, e);
576 }
577 }
578 }
579
580
581
582
583 public abstract static class JcaAgreementBase
584 extends GordianCoreAgreementEngine {
585
586
587
588 static final byte[] EMPTY = new byte[0];
589
590
591
592
593
594
595
596
597 JcaAgreementBase(final GordianCoreAgreementFactory pFactory,
598 final GordianCoreAgreementSpec pSpec) throws GordianException {
599
600 super(pFactory, pSpec);
601 }
602
603 @Override
604 protected GordianPublicKey getPublicKey(final GordianKeyPair pKeyPair) throws GordianException {
605
606 if (!(pKeyPair instanceof JcaKeyPair)) {
607
608 throw new GordianDataException("Invalid KeyPair");
609 }
610
611
612 return super.getPublicKey(pKeyPair);
613 }
614
615 @Override
616 protected GordianPrivateKey getPrivateKey(final GordianKeyPair pKeyPair) throws GordianException {
617
618 if (!(pKeyPair instanceof JcaKeyPair)) {
619
620 throw new GordianDataException("Invalid KeyPair");
621 }
622
623
624 return super.getPrivateKey(pKeyPair);
625 }
626
627
628
629
630
631
632
633 void initAgreement(final KeyAgreement pAgreement,
634 final JcaPrivateKey pPrivate) throws GordianException {
635
636 try {
637 if (getSpec().getKDFType() == GordianAgreementKDF.NONE) {
638 pAgreement.init(pPrivate.getPrivateKey(), getRandom());
639 } else {
640 pAgreement.init(pPrivate.getPrivateKey(), new UserKeyingMaterialSpec(getAdditional()), getRandom());
641 }
642 } catch (InvalidKeyException
643 | InvalidAlgorithmParameterException e) {
644 throw new GordianCryptoException(ERR_AGREEMENT, e);
645 }
646 }
647
648
649
650
651
652
653 byte[] getAdditional() {
654 final byte[] myAdditional = this.getBuilder().getState().getAdditionalData();
655 return myAdditional == null ? EMPTY : myAdditional;
656 }
657
658
659
660
661
662
663
664
665
666 KeyAgreement adjustAgreement(final KeyAgreement pCurrent,
667 final GordianKeyPair pKeyPair) throws GordianException {
668
669 if (getSpec().getKeyPairSpec().getKeyPairType().equals(GordianKeyPairType.XDH)) {
670 final String myBase = pKeyPair.getKeyPairSpec().toString();
671 final String myXtra = GordianAgreementType.UNIFIED.equals(getSpec().getAgreementType())
672 ? "U" : "";
673 final String myName = getFullAgreementName(myBase + myXtra, getSpec());
674 return getJavaKeyAgreement(myName, false);
675 }
676
677
678 return pCurrent;
679 }
680
681
682
683
684
685
686 AlgorithmIdentifier derivationAlgorithmId() {
687 final GordianCoreAgreementSpec mySpec = getSpec();
688 return switch (mySpec.getKDFType()) {
689 case SHA256KDF ->
690 new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf2, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256));
691 case SHA512KDF ->
692 new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf2, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512));
693 case SHA256CKDF ->
694 new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256));
695 case SHA512CKDF ->
696 new AlgorithmIdentifier(X9ObjectIdentifiers.id_kdf_kdf3, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512));
697 case SHA256HKDF -> new AlgorithmIdentifier(PKCSObjectIdentifiers.id_alg_hkdf_with_sha256, null);
698 case SHA512HKDF -> new AlgorithmIdentifier(PKCSObjectIdentifiers.id_alg_hkdf_with_sha512, null);
699 case KMAC128 -> new AlgorithmIdentifier(NISTObjectIdentifiers.id_Kmac128, null);
700 case KMAC256 -> new AlgorithmIdentifier(NISTObjectIdentifiers.id_Kmac256, null);
701 case SHAKE256 -> new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256, null);
702 default -> null;
703 };
704 }
705 }
706
707
708
709
710
711
712
713
714 static KeyGenerator getJavaKeyGenerator(final GordianKeyPairSpec pSpec) throws GordianException {
715
716 try {
717
718 String myName = pSpec.getKeyPairType().toString();
719 final GordianCoreKeyPairSpec mySpec = (GordianCoreKeyPairSpec) pSpec;
720 switch (pSpec.getKeyPairType()) {
721 case NTRUPRIME:
722 final GordianCoreNTRUPrimeSpec myNTRUSpec = mySpec.getNTRUPrimeSpec();
723 myName = myNTRUSpec.getType() + "PRIME";
724 break;
725 case MLKEM:
726 myName = "ML-KEM";
727 break;
728 default:
729 break;
730 }
731
732
733 final Provider myProvider = mySpec.getCoreKeyPairType().isStandardJca() ? JcaProvider.BCPROV : JcaProvider.BCPQPROV;
734
735
736 return KeyGenerator.getInstance(myName, myProvider);
737
738
739 } catch (NoSuchAlgorithmException e) {
740
741 throw new GordianCryptoException("Failed to create KeyGenerator", e);
742 }
743 }
744
745
746
747
748
749
750
751
752
753 static KeyAgreement getJavaKeyAgreement(final String pAlgorithm,
754 final boolean postQuantum) throws GordianException {
755
756 try {
757
758 return KeyAgreement.getInstance(pAlgorithm, postQuantum
759 ? JcaProvider.BCPQPROV
760 : JcaProvider.BCPROV);
761
762
763 } catch (NoSuchAlgorithmException e) {
764
765 throw new GordianCryptoException("Failed to create KeyAgreement", e);
766 }
767 }
768
769
770
771
772
773
774
775
776
777 static String getFullAgreementName(final String pBase,
778 final GordianCoreAgreementSpec pAgreementSpec) throws GordianException {
779 return switch (pAgreementSpec.getKDFType()) {
780 case NONE -> pBase;
781 case SHA256KDF -> pBase + "withSHA256KDF";
782 case SHA512KDF -> pBase + "withSHA512KDF";
783 case SHA256CKDF -> pBase + "withSHA256CKDF";
784 case SHA512CKDF -> pBase + "withSHA512CKDF";
785 case SHA256HKDF -> pBase + "withSHA256HKDF";
786 case SHA512HKDF -> pBase + "withSHA512HKDF";
787 default -> throw new GordianDataException(GordianBaseData.getInvalidText(pAgreementSpec));
788 };
789 }
790 }