Skip to content

Commit 9ec242f

Browse files
committed
generalized proxy private key public key usage.
added bounds checking on mu.
1 parent 1503a6c commit 9ec242f

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

Diff for: prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/mldsa/SignatureSpi.java

+26-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.bouncycastle.jcajce.provider.asymmetric.mldsa;
22

33
import java.io.ByteArrayOutputStream;
4+
import java.io.IOException;
45
import java.security.InvalidKeyException;
56
import java.security.NoSuchAlgorithmException;
67
import java.security.PrivateKey;
@@ -9,11 +10,14 @@
910
import java.security.SignatureException;
1011

1112
import org.bouncycastle.crypto.CipherParameters;
13+
import org.bouncycastle.crypto.DataLengthException;
1214
import org.bouncycastle.jcajce.MLDSAProxyPrivateKey;
15+
import org.bouncycastle.jcajce.interfaces.MLDSAPublicKey;
1316
import org.bouncycastle.jcajce.provider.asymmetric.util.BaseDeterministicOrRandomSignature;
1417
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
1518
import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters;
1619
import org.bouncycastle.pqc.crypto.mldsa.MLDSASigner;
20+
import org.bouncycastle.pqc.crypto.util.PublicKeyFactory;
1721

1822
public class SignatureSpi
1923
extends BaseDeterministicOrRandomSignature
@@ -80,12 +84,19 @@ protected void signInit(PrivateKey privateKey, SecureRandom random)
8084
}
8185
}
8286
}
83-
else if (privateKey instanceof MLDSAProxyPrivateKey)
87+
else if (privateKey instanceof MLDSAProxyPrivateKey && this instanceof MLDSACalcMu)
8488
{
8589
MLDSAProxyPrivateKey pKey = (MLDSAProxyPrivateKey)privateKey;
86-
BCMLDSAPublicKey key = (BCMLDSAPublicKey)pKey.getPublicKey();
90+
MLDSAPublicKey key = pKey.getPublicKey();
8791

88-
this.keyParams = key.getKeyParams();
92+
try
93+
{
94+
this.keyParams = PublicKeyFactory.createKey(key.getEncoded());
95+
}
96+
catch (IOException e)
97+
{
98+
throw new InvalidKeyException(e.getMessage());
99+
}
89100

90101
if (parameters != null)
91102
{
@@ -208,6 +219,10 @@ protected byte[] engineSign()
208219

209220
return signer.generateMuSignature(mu);
210221
}
222+
catch (DataLengthException e)
223+
{
224+
throw new SignatureException(e.getMessage());
225+
}
211226
catch (Exception e)
212227
{
213228
throw new SignatureException(e.toString());
@@ -221,7 +236,14 @@ protected boolean engineVerify(byte[] sigBytes)
221236

222237
bOut.reset();
223238

224-
return signer.verifyMuSignature(mu, sigBytes);
239+
try
240+
{
241+
return signer.verifyMuSignature(mu, sigBytes);
242+
}
243+
catch (DataLengthException e)
244+
{
245+
throw new SignatureException(e.getMessage());
246+
}
225247
}
226248
}
227249

Diff for: prov/src/test/java/org/bouncycastle/pqc/jcajce/provider/test/MLDSATest.java

+45
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.security.SecureRandom;
1515
import java.security.Security;
1616
import java.security.Signature;
17+
import java.security.SignatureException;
1718
import java.security.spec.InvalidKeySpecException;
1819
import java.security.spec.PKCS8EncodedKeySpec;
1920
import java.security.spec.X509EncodedKeySpec;
@@ -549,6 +550,50 @@ public void testMLDSAMuKatTest()
549550
assertTrue(sigImpl.verify(sig));
550551
}
551552

553+
public void testMLDSAMuExceptionTest()
554+
throws Exception
555+
{
556+
// mu shortened by 1 byte
557+
byte[] mu = Hex.decode("FA27834894431BAA18EB0353DA5383BCFD8585E60F1A4382566E0D85E0519F67084AC615088A85074D901D8DBD36AE487B23281E1172F6C03C8CD31A4B683B");
558+
byte[] sig = Hex.decode("146E97D0704552E762FBF3B0387C255B381D84A1B98EACAF572E71EB0317133758BBF3631CA6C3412238327AEA511432CCF868841BC7F71E484DDB8158E20687AFA3381DC14B96E045036AF004955CF7C9BC9DBCDD3EE558C73E9E16AAD91603E0D839294684B358559F0B2278B5ABB6224395E02849CD7E4DC52805058809674D9CC79744A25436AFBBEB77784F6F85ABF315E963794270C763128F5EDB8E390E0CD2328B868FF6AEE3BC1DE73DC66DBD9D967E9BD1E0E96008C8678C5C28ED73349C297E86DEFC00653E97D873DD6443E4164A0D5231E8C9EFB4EA2F068FECA57BDAEA4A7989C96ED307A578013F705073E875B045CDDF8D131DC6A72DD4EB63495C0DDF53706EB43E44B7B4FAD7C835CB6E9C0D771894A11289A43D3454E4FC8301C9CEC180EAD4B763D332E4760CFE2DDCA5893D0190E6BB7E36E9B596AE714B5B30C65BA0B0675595BDED190BCEA2450063BA157E4CE7DAC45F66FC270BB0608C82196F5EAC4B53C5E2F8C59C3D18222428F935EB3F4E54C1FE7DE4BFDE305C2AFC36C91894387DDDC957C4D2737E9FCDE5C7CAE453A4C45D4FE10A811C78179D6DDB4E33F5E374245EBC3D3DEA4351C8F55E10CD0F79B70010E897BD3F376F7693937F2DF58A7BAB9A0AF5595E3383C426DEC394EBE410C026A2F3E6B2E8200BDAAF15F33DFA4ADEBD59F386AE6C8F097E1183CA9577FFC008C710705DC73A87B6EDBACC23CC8C4FE652916CF8DDFFBACB92EF6BAA668E5772A0A06A2F4DE1F307ABDF6A028BE7F82ECECDA72A411CFBF377B1B3B2AB731563611F8BC933478913A8C1FFF1BB7C76F7B6E55125A41A4FC12C306349546AEA527FA24C0815AAAF8AA3E5367654A6B2BBC886804F25A57E64EAFC0E1D3F805979500A7EF16AE8F0A6E13A3DB3B72A9A91B9D11D9C1A19A0300663C7E931A4AD5EB503EE6F4F7264B66C43C98AB26A5DC42BEFEBC5CAEDC08F7B328C5556B904AA173867737AB3EAEA09722680DF5CB5EF3A1C0D549731EF800D0C72AE8D90BD6C21BB4F4F0E2F4147181C4054F29EAB4A0AFCA49E7406C1A711F38659A638646E5CB3C142747EF843F6517A905F70BD93818816641A45C894E2D44E6CAB7DA0524C9998AF62EF0047CE1A7C5EDD490938402FB1B7015273FBDEB85E536946F0AB7051062536ACD21BAD2311E4A45AF17714426645293EF0D6266DB59692DD99286ABA0C9C77581ECE32CC4C7FBFABA55D719E35E68FC0A6C7031F999BB08153C2501FD61BEA99198DEF0C514A6A1A8FF6E5D9411BC0B7BD2B66E364AF51D007F49DC9E2A756396B1842BF6FCDDF0A2F9E8AF485AB8AF4653FB1F9570E99633DD4914624177CF3D2027053B0BA0D60FBCFEF92EAD69494C56D2717C427666AA313884FAC83BC42DAF224826E127F4B33A6340DEB52942E2792D90023FEBFC935E5B18C6EC8B2A6861C3F2C929A3FFA38C2DD23A97EBAA2CC694199BE95E93BDA5C4CBD13712D03A0C3CDC1F0A1C9B64A88F0E752A167F8F093077CA73B538A8738EA7F2B878A29FAA7D42266FCE8CF16A9BB413FD50FCF6057F77E16C916704AE7622AF72D666AD06C2596E9CE3A297786C134A430441958484EB058C8DB19D1A6E788336D67D52E877CEB4C9F204E4D995FE2685AAB6EEFCFA6D0FD1D61B0C8F532953B32642A34657BFBAD90B8F0C85A821054770C6A2E27D8CE315618DB82EA24A1D486C12934EBC9133F38B72481748B8C9D432A3D1E1AF85DEFB2BEE0C155006BE17E879811E2FE08A337D54A03E5884384000DE817A3D9BBE94941A52A58ECE851F605B9F69E1C3112CFF92AB332D6E694A65EFD58ED61F57F84947A75A5C9776A9A7FD187C5015425ED708DC242CDAA30BEE759BBD9CBB046DF3F4D54F481208216AF5CA7892150DD9829A3AB540BBFCFC2E303E9205ABB4D65D7287B5BBCC85F8987AD7B182058E36DA5C37FE5658138ED49D65B11B67360A1FEE9E44D2D2C3164BEF63B426DB495540B383AAE5F54283F91B1E543F7F965289CB9F64928E6AC208D9791DE234ABA43FC2B44D89317277136F791C782A773340998C526015C0415211676F53BDCE809974D6450E39CA2C814F644D75CB4F349D28EDF08B1CE58616D16816B4C021C5F16CCD5FB539BEFA6C9F03704FFE1010589350C20AE319545B0E39AE7CAA7FCED9A3D2151ACF6CBAB5FBB0D0E83313A45E6209046BF1A89D5F808969CC62167B014E969EAD6B2088B7738FAB3D277D1CDD6F4C6816B847AD1D30083F77564CABEB55CB4A8BB8C6BD47A59B6772DCCC8431A01C04184965B8F25BF8333281AC7686852FAFD77B374E76D8839CFE1F594E212531325F0CD6F8C2853194B4D668F843776F0E563E00CBBE6F5D6EBE4EBC11A5F70D3872F669939BD4A21A26FCD836DB79EC271CB463A521264DD62CD0A664B1EF3D7B4C84793F2B9C36369BEB651858CA9D5DCA23D6F8137C6C1F96FEE19DD3A4CD08A4FD4CD579F0F994E302A62F37121189B2A61E8591A98E0396766047B77E8D4533E62891B77AD0F7607DC0AF1D7D327E8E7B45991A508B5B22FD3398BEA7F80966EBEF5A1ACF9F5FCCF9C0C6E61A05DBB583EB048CAA41C28E87530820D21E90BFD2CFF29C8FEC2F7F1FC90605F2C84553A709CB9F53C1BDF12DC20524E76870ACB7624AD238B5BB8EEC8D5D37F02F12D1DF2384E7EC70CFDCC25831305682080326E702795ABFC6DF60BE923AB245887A35EB5EC00B7A109F86A8F7DCF2E59DBD8C4C9D645588F4D25C768F499C3FA65C98FEB48B07A4B01C7AF8AF28ADBC5C487A5C1FB059EF91B3A77C8321126978B5EAD648BB96C6210C6EF505B6E40098E415E0324D1CCD0A5B0560455BA894AD84CFA8E9B37706EFC23B00513BA3D6DF77D38E203AAD4E718286BE73A729C7CB2CB2EEC65726EA48E657DA31A548972B21642C01512421A21E2A4151A995CDC2DA9A7602E747CB62C893D555BA4455ACD880282459257622B370F3AEE7C99C2D8CD31050E6F1050340EB287BE92133C2479F07780ED355CC124FBDD2C7ADC2A129DA3A99C964F1BB32B5609C36ABB69AFABC0F1445362DFBE2A381C3D88973EDFF9D98ECD0E5EDA94D394B784ABC97470283FBB87403A5DCD4BCF55F24F4368BDE39E63E3C906FD2EA6C4103EF571FCD269700472C761B2E2C52F9F10C195C7947AE378B40724499C8EB3AE5ED4B3B06DCE02F29424662BF209AA14D39C1EEC5E3E5DE7B7CADFD1D8ED9D0AA552FF54353F0E9BD1CD02965A47D83F1359BE6FE0C0144BC0EA8BD2C37CAB4DFBEEB31833F4146316023C4D556C7C8093C3CAD4E7040B122B375963767893A9B4DEE5EDEEFAFC0409121A326F7072A2ACD5DCEEF1F2F4FD051E26373B3F464B97999A9B9FA4ABC9E2FDFE00000000000000000000000000000C1E2F42");
559+
560+
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA", "BC");
561+
562+
kpg.initialize(MLDSAParameterSpec.ml_dsa_44, new SecureRandom());
563+
564+
final KeyPair kp = kpg.generateKeyPair();
565+
566+
Signature sigImpl = Signature.getInstance("ML-DSA-EXTERNAL-MU", "BC");
567+
568+
sigImpl.initVerify(kp.getPublic());
569+
570+
sigImpl.update(mu, 0, mu.length);
571+
try
572+
{
573+
sigImpl.verify(sig);
574+
fail("no exception");
575+
}
576+
catch (SignatureException e)
577+
{
578+
assertEquals("mu value must be 64 bytes", e.getMessage());
579+
}
580+
581+
sigImpl.initSign(kp.getPrivate());
582+
583+
sigImpl.update(mu, 0, mu.length);
584+
585+
try
586+
{
587+
sigImpl.sign();
588+
fail("no exception");
589+
}
590+
catch (Exception e)
591+
{
592+
assertEquals("mu value must be 64 bytes", e.getMessage());
593+
}
594+
595+
}
596+
552597
public void testMLDSAKATSig()
553598
throws Exception
554599
{

0 commit comments

Comments
 (0)